构造函数为类对象分配内存空间。
构造函数是C++中用于初始化对象状态的特殊函数
构造函数在对象创建时自动被调用(默认调用),隐身调用
构造函数和普通成员函数一样尊重重载规则
拷贝构造函数是对象正确初始化的重要保证
必要时,必须手工编写拷贝构造函数
class Demo {
public:
Demo() { //无参数构造函数
a = 0;
b = 0;
p = NULL;
}
Demo(int _a, int _b, char * _p) { //带参构造函数
a = _a;
b = _b;
p = _p;
}
Demo(const Demo &obj) { //拷贝构造函数,用其它对象初始化
a = obj.a;
b = obj.b;
p = obj.p;
}
protected:
private:
int a;
int b;
char * p;
};
1、当类中没有定义任何一个构造函数,C++编译器会提供无参构造函数和拷贝函数
2、当类中定义了任意的非拷贝构造函(无参、带参数),C++编译器不会提供无参构造函数
3、当类中定义了拷贝构造函数时,C++编译器也不会提供无参构造函数
也就是只要人为提供了构造函数无论是无参、带参构造函数还是拷贝构造函数,编译器都不会再提供无参构造。
void fun(Demo d) { //将实参赋给形参的时候,也会调用构造函数,如果是指针或者引用就不会
//......
}
Demo getDemo() { //返回生成的一个匿名对象
Demo dd; //无参构造
return dd; //将dd拷贝构造给匿名对象
}
int main()
{
Demo d1; //无参构造
Demo d2=d1; //拷贝构造
Demo d3(d2); //拷贝构造
Demo d4 = Demo(1, 2, NULL); //带参构造
Demo d5; //无参构造,浪费时间
d5 = getDemo(); //将匿名对象赋值给d5
Demo d6 = getDemo(); //这个时候不会像上面一样调用构造函数,为了节约时间,直接将匿名对象转成d6对象
return 0;
}
注意:编译器提供的拷贝构造都是浅拷贝,那么浅拷贝和深拷贝的区别是什么呢?
对象2是对象1的浅复制,对象3是对象1的深复制,他们的区别在于浅复制只会copy对象中的变量,而不会复制成员指针变量所指向的内存空间。编译器提供的都是浅拷贝,深拷贝需要人为去定义。
还需要注意一项就是编译器提供的析构函数不会释放成员指针所指向的内存,需要人为去释放。
构造函数有个特殊的问题:
class Test {
public:
Test() {
}
Test(int _a, int _b) {
a = _a;
b = _b;
Test(1, 3, 4);//这个时候c会不会被赋值呢????
}
Test(int _a, int _b, int _c) {
a = _a;
b = _b;
c = _c;
}
protected:
private:
int a;
int b;
int c;
};
int main() {
Test t(1, 2);
}
对象t中的c会不会被赋值呢?不会。构造函数中Test(1,3,4)只会生成一个匿名对象然后消失。并不会给对象t的c成员变量赋值。