构造函数是类中的一个特殊成员函数,它一般为公有的。在特殊的情况下它可能为私有的。此时这个类将会无法新建对象。当有一个对象被新建时,构造函数会被自动的调用,这种机制能够确保正确的初始化。在一个空类中,构造函数是默认生成的。但如果我们写了一个构造函数之后,便不会再生成默认的构造函数。一般的,在创建对象的时候构造函数会被自动调用,在方法结束之后析构函数会被自动调用。但如果是new出来的对象就需要我们手动的去delete析构函数才会被调用。
假设定义了一个ClassDemo的类。
class ClassDemo
{
public:
ClassDemo();
ClassDemo(int num);
~ClassDemo();
private:
int _num;
};
ClassDemo array[10];
这种情况下面无参的构造函数会被调用十次
ClassDemo array[10] = {1};
此时有参的构造函数被调用一次,无参的构造函数被调用十次
ClassDemo *demo = static_cast<ClassDemo*>(molloc(sizeof(ClassDemo)));
free(demo);
此时既不会调用构造函数也不会调用析构函数,它只是单纯的分配一个空间。所以在c++中在堆区新建一个对象应该使用new和delete。
ClassDemo demo = 10;
此时的”=”并非一个赋值语句,它会调用带一个参数的构造函数。基于这个特性,将带一个参数的构造函数叫为转换构造函数。此时这句话等同于ClassDemo demo(10);
ClassDemo demo = 10;// 此时调用转换构造函数
demo = 20; // 此时调用赋值函数
在demo = 20这句话中会做三件事情:1.通过构造函数新建一个临时的对象。2.将该临时对象传给默认的赋值函数。3.析构该临时对象
默认的赋值函数就像默认的构造函数一样,在一个空类中是会默认生成的。它和默认构造函数不同的是我们写了一个构造函数之后默认的构造函数是不会生成的,而写了赋值函数之后默认的赋值函数同样会生成
ClassDemo& operator=(const ClassDemo &other)
{
_num = other._num;
return *this;
}
这就是默认赋值函数的实现方式。
其实它的实质是将一个int型的数据隐式转换为ClassDemo类型,再将转换后的类型传递给operator=()函数。如果没有转换构造函数这个隐式的转换便无法执行。此时通过重载=运算符接收一个int型数据即可。
如果想避免这种隐式的转换,在转换构造函数前面加上explicit关键字即可。