您的位置:首页 > 编程语言 > C语言/C++

c++:(各种)构造函数的调用方式

2017-03-08 13:07 260 查看
c++的类中有5种值得注意的基本的函数:

无参构造函数

有参构造函数

拷贝构造函数

赋值函数

析构函数

关于析构函数,需要注意的点在上一篇博客里面 c++: 是否会自动delete? 也提到过了,在这里暂时不多说。这篇博客主要记录这3个构造函数、1个赋值函数的调用方式,希望大家学习之后,不但知道如何调用,还可以根据一句话来判断到底调用了几次构造函数。

可以通过一个例子来说明,假如我现在有一个Animal类,其中为了调试,我特意在每个构造函数中加入了输出语句,来看看调用的结果:

struct Animal {
int age;
string name;

Animal() {  // 无参构造函数
cout << "No-args Constructor" << endl;
age = -1;
name = "Unknown";
}

Animal(string name, int age) { // 有参构造函数
cout << "Argumenting Constructor" << endl;
this->name = name;
this->age = age;
}

Animal(const Animal &other) { // 拷贝构造函数
cout << "Copy constructor" << endl;
this->name = other.name;
this->age = other.age;
}

Animal& operator=(const Animal &other) { // 赋值函数
cout << "Assigning" << endl;
this->name = other.name;
this->age = other.age;
}

~Animal() {
cout << "Destructor" << endl;
}

friend ostream& operator<<(ostream &out, const Animal &animal) {
out << "Animal[" << animal.name << "]: " << "age=" << animal.age;
return out;
}
};


然后,以下代码会演示创建一个实例的多种方式,并且我把每一种创建方式的输出结果、以及一些思考,以注释的方式写出来:

int main() {

//-----------------无参构造函数-----------------------

Animal animal01; // 虽然不是很明显,但是这里不是使用指针,而是直接操作实例,所以这里实际上调用了无参构造函数。
cout << animal01 << endl;
/*
输出:
No-args Constructor
Animal[Unknown]: age=-1
*/

Animal animal02(); // 这并不能调用无参构造函数!编译器会当作是某个函数的声明,所以下面输出的1也许是函数的地址(暂时没有深究)。
cout << animal02 << endl;
/*
输出:
1
*/

Animal animal03 = Animal();
// 注意,这里可能有人会认为:等号右边调用了默认构造函数,然后因为赋值给左边所以又调用了一次拷贝构造函数,就会认为这样子会白白浪费掉一个实例。
// 实际上,根据输出可以看到,结果并不是上述那样,而是这个语句整体上只调用了一次无参构造函数。即与“Animal animal03;”效果一样。
cout << animal03 << endl;
/*
输出:
No-args Constructor
Animal[Unknown]: age=-1
*/

//----------------------------------------------

//-----------------有参构造函数-----------------------

Animal animal001("Lion", 1);
cout << animal001 << endl;
/*
输出:
Argumenting Constructor
Animal[Lion]: age=1
*/

Animal animal002 = Animal("Lion", 1);
// 这里同上面所说的,整体上仅仅调用了一次有参构造函数。
cout << animal002 << endl;
/*
输出:
Argumenting Constructor
Animal[Lion]: age=1
*/

//----------------------------------------------

//----------------拷贝构造函数-------------------

Animal animal0001 = animal001;
// 这里要区分“拷贝构造函数”和“赋值函数”的调用时机。前者是声明和赋值在同一行,后者不是。所以这里属于拷贝构造函数。
cout << animal0001 << endl;
/*
输出:
Copy constructor
Animal[Lion]: age=1
*/

//-------------------------------------------

//------------------赋值函数------------------------

Animal animal;
animal = animal0001;
// 因为这里animal的声明和赋值不在同一行,所以编译器会认为不是拷贝构造,而是一般的赋值语句。
cout << animal << endl;
/*
输出:
No-args Constructor
Assigning
Animal[Lion]: age=1
*/

//-----------------------------------

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 构造函数