构造函数
构造函数并不负责空间,它只是用来初始化成员变量.
当用户没有定义构造函数时,编译生成默认构造函数,默认构造函数不进行任何操作.
一个类可以有多个构造函数.多个构造函数之间成重载关系.
#include <iostream>
using namespace std;
class Sample
{
int x;
public:
Sample()
{
cout<<"constructor 0 called"<<endl;
}
Sample(int n)
{
x = n;
cout<<"constructor 1 called"<<endl;
}
};
int main()
{
Sample p1[2] = {1,2};
cout<<endl;
Sample p2[2] = {1};
cout<<endl;
return 0;
Sample *p3 = new Sample[2];
delete [] p3;
}
运行结果如下:
step1:
constructor 1 called
constructor 1 called
step2:
constructor 1 called
constructor 0 called
step3:
constructor 0 called
constructor 0 called
复制构造函数
当用户没有定义复制构造函数时,编译生成默认复制构造函数,默认复制构造函数的功能是生成一个完全相同的新对象.
下面三种情况时.复制构造函数会被调用:
1.使用一个对象初始化一个新对象时.
2.对象作为函数参数传递时.
3.对象作为函数返回值时(这种情况是否调用与编译器有关).
#include <iostream>
using namespace std;
class Sample
{
public:
int x;
Sample(const Sample &n)
{
x = n.x;
cout<<"copyConstructor called"<<endl;
}
Sample(int n)
{
x = n;
}
Sample()
{}
};
void f1(Sample a)
{}
Sample f2()
{
Sample a(4);
return a;
}
int main()
{
Sample p1;
cout<<"step1:"<<endl;
Sample p2 = p1;
cout<<"step2:"<<endl;
Sample p3;
p3 = p1; //不是初始化,所以不会调用复制构造函数
cout<<"step3:"<<endl;
Sample p4(p1);
cout<<"step4:"<<endl;
f1(p1);
cout<<"step5:"<<endl;
int n = f2().x; //这种情况是否调用与编译器有关
return 0;
}
VS2013的运行结果:
step1:
copyConstructor called
step2:
step3:
copyConstructor called
step4:
copyConstructor called
step5:
copyConstructor called
clang6.0.0和gcc7.3.0的运行结果:
step1:
copyConstructor called
step2:
step3:
copyConstructor called
step4:
copyConstructor called
step5:
类型转化构造函数
类型转化函数会生成一个临时对象.
#include <iostream>
using namespace std;
class Sample
{
public:
int x;
Sample(int n) // 类型转化函数
{
x = n;
cout<<"X:"<<x<<"conversionConstructor called"<<endl;
}
Sample()
{}
~Sample ()
{
cout<<"destructor called"<<endl;
}
};
int main()
{
Sample p1(3);
p1 = 2;
cout<<"mainend"<<endl;
}
输出如下,注意析构函数被调用了两次.第一次就是临时对象消亡时的调用:
X:3conversionConstructor called
X:2conversionConstructor called
destructor called
mainend
destructor called