默认情况下,C++编译器给一个类添加至少三种函数:
1、无参构造函数(函数体为空):主要是创建对象时系统自动调用从而为成员变量赋值。
2、拷贝构造函数:对属性值进行拷贝。
3、析构函数(无参,函数体为空):主要是销毁对象时系统自动调用从而执行一些清理工作。
但是,如果用户自定义了有参构造函数或者拷贝构造函数,则编译器不再提供无参构造函数(即第一点)。
无参构造函数、有参构造函数和拷贝构造函数,这三种构造函数的“调用”方式都有三种:括号法、显示法、隐式转换法。
注:这里的调用不一定是人为的调用,也有编译器自动调用。
class Person{
public:
Person(){
cout << "构造函数" << endl;
}
Person(int a){
cout << "有参构造函数" << endl;
}
Person(const Person &a){
cout << "拷贝构造函数" << endl;
}
}
void test(){
// 调用构造函数
// 1、括号法
Person p1; // 默认
Person p2(10); // 有参
Person p3(p2); // 拷贝
Person p4(); // 这种方法是错的,编译器会理解成声明函数
// 2、显示法
Person p5 = Person(10); // 有参
Person p6 = Person(p1); // 拷贝
Person(10); // 匿名对象,执行结束后系统会立即回收掉匿名对象
Person(p6); // 这种写法是错的,编译器会认为是Person p6,就重复定义了
// 3、隐式转换法
Person p7 = 10; // 有参
Person p8 = p7; // 拷贝
}
int main(){
test();
return 0;
}
其中,拷贝构造函数的“调用”方式除了下列已提到的第一点,还有后面两种:
1、使用一个对象来初始化另一个新的对象
2、值传递时会自动调用拷贝构造函数
3、值返回时会自动调用拷贝构造函数
class Person{
public:
Person(){
cout << "构造函数" << endl;
}
Person(int a){
cout << "有参构造函数" << endl;
}
Person(const Person &a){
cout << "拷贝构造函数" << endl;
}
}
void doWork1(Person p){
}
Person doWork2(){
Person p5;
return p5;
}
void test(){
// 1、使用一个对象来初始化另一个新的对象
Person p1(10);
Person p2(p1);
// 2、值传递时会自动调用拷贝构造函数
Person p3;
doWork1(p3);// 这里会拷贝,p3和函数参数里的p不是同一个
// 3、值返回时会自动调用拷贝构造函数
Person p4;
p4 = doWork2();// 返回的对象是经过拷贝了的
}
int main(){
test();
return 0;
}
析构函数又有注意事项。
class Person{
public:
~Person(){
cout << "析构函数" << endl;
}
}
void test(){
Person p;
}
int main(){
// 会调用析构函数,函数内的局部变量存放在栈区,在函数调用结束后会自动释放内存。
test();
// 不会调用析构函数
Person p;
return 0;
}