只要创建了一个类编译器会默认创建三个构造,
1.无参构造
2.有参构造
3.拷贝构造
这三个函数你不写编译器就自动用编译器默认的,你写了就用你的。
// 构造函数和析构函数 // 类实例化一个对象时强制调用构造函数,对象销毁后自动调用析构函数进行清理工作。 // 如果没有手动写出构造和析构函数,编译器会自动补上,只不过是空实现。 #includeusing namespace std; class fun { public: // 如果私有化 则该类将不能在外部实例化对象 fun() { // 没有返回值也不写void // 构造函数一般进行初始化的工作。 // 可以有形参,可以重载,有参数的是有参构造,该构造为无参构造 // 创建对象时会自动调用构造且只会调用一次。 cout << "构造函数被调用!" << endl; } fun(int a) { cout << "有参构造 " << a << endl; } // 析构函数 语法 " ~类名(){} " ~fun() {// 没有返回值也不写void // 析构函数进行清理工作。 // 析构函数没有形参,不能发生重载。 // 析构函数在对象死亡的时候被自动调用且只调用一次。 cout << "析构函数被调用!" << endl; } }; class Person { int age; public: // 普通构造函数 Person(){ } Person(int a) { } // 拷贝构造函数 // 不写拷贝构造函数时,系统默认提供,拷贝p的所有属性到新的对象中 Person(const Person& p) { // 拷贝时不能修改本体所以要写const age = p.age; } }; // 调用 void test(){ Person p1; // 默认构造的调用 // 1.括号法 Person p2(10); // 调用有参构造函数 Person p3(p2); // 括号法调用拷贝构造函数 // 注意:1、调用默认构造时 不要加括号。 // Person pp(); // 编译器认为这是函数的声明,而不是创建对象。 // 2.显示法 Person p4 = Person(10); // 调用有参构造 Person p5 = Person(p4); // 显示法调用拷贝构造 Person(10); // 创建匿名对象,特点:当前行运行结束后会立即调用它的析构函数结束对象的生命 // Person(p3); // 注意:2、不要利用匿名实例化对象调用拷贝构造。 // 编译器会认为这是个对象的声明 Person(p3) === Person p3; // 编译器就会报语法错误,p3重定义 // 3.隐式转换法 Person p6 = 10; // 相当于 Person p6 = Person(10); Person p7 = p6; // 隐式法 调用 拷贝构造 } class ccopy { public: int age; public: ccopy() { } ccopy(int age) { this->age = age; } ccopy(const ccopy & c) { this->age = c.age + 1; // 这样写测试更明显 } ~ccopy() { } }; void dowork(ccopy p) { // 这里实参传入时会触发拷贝构造函数 // 我们将拷贝构造函数修改为 新对象时旧对象的age+1; cout << "拷贝打印 " << p.age << endl; // 这里打印2 因为拷贝构造中 cc1.age+1 == 2 } ccopy dowork2() { ccopy c(1); return c; // 这里函数结束后栈被释放, //但是释放前拷贝了c对象,所以返回 通过触发拷贝构造 产生的对象 } void text01() { // 拷贝函数的调用时机 // 1.使用一个已经初始化完毕的对象来初始化一个新对象。 ccopy c1(10); ccopy c2 = c1; // 2.值传递的方式给函数参数传值 ccopy cc1(1); dowork(cc1); // 调用形参为ccopy对象的函数 传入的cc1 age==1; // 3.值方式返回局部对象 ccopy cc2 = dowork2(); // 这里cc2.age == 2; // 因为调用函数dowork2 时触发拷贝 // dowork2中实例化了c对象然后栈销毁前触发拷贝构造c.age+1 == 2 cout << "cc2 == " << cc2.age << endl; // cc2 == 2 } int main() { text01(); //fun f; return 0; }
如果你写了拷贝构造函数,编译器将不会提供其他的构造函数
class demo {
public:
demo(const demo& d) { // 只写拷贝构造
}
};
void t_demo() {
demo d; // 这里实例化不了demo对象。因为没有构造函数
}



