首先我们知道只要创建一个类编译器会提供三个默认函数
1.默认构造函数 (无参,空实现)
2.默认析构函数(无参,空实现)
3.默认拷贝构造函数,对值属性进行拷贝
调用规则如下
1.如果我们定义有参构造函数,编译器不会提供默认构造函数,但提供默认拷贝构造函数
2.如果用户定义了拷贝构造函数,编译器将不会提供其他构造函数
1 #include2 using namespace std; 3 4 class person 5 { 6 public: 7 person() 8 { 9 puts("默认构造函数调用");10 }11 12 person(const person &p)13 {14 m_age = p.m_age; 15 puts("拷贝构造函数调用");16 }17 18 person(int age)19 {20 m_age = age;21 puts("有参构造函数调用");22 }23 24 ~person()25 {26 puts("析构函数调用");27 }28 29 int m_age;30 };31 32 void test()33 {34 person p;35 p.m_age = 18;36 person p2(p);37 cout << p2.m_age << endl; 38 }39 40 int main()41 {42 test();43 return 0;44 }
1 #include2 using namespace std; 3 4 class person 5 { 6 public: 7 person() 8 { 9 puts("默认构造函数调用");10 }11 12 // person(const person &p)13 // {14 // m_age = p.m_age; 默认拷贝构造函数会执行这里,把所有值属性拷贝 15 // puts("拷贝构造函数调用");16 // }17 18 person(int age)19 {20 m_age = age;21 puts("有参构造函数调用");22 }23 24 ~person()25 {26 puts("析构函数调用");27 }28 29 int m_age;30 };31 32 void test()33 {34 person p;35 p.m_age = 18;36 person p2(p);37 cout << p2.m_age << endl; 38 }39 40 int main()41 {42 test();43 return 0;44 }
下面代码证明了定义有参构造函数,编译器不会提供默认构造函数,但提供默认拷贝构造函数
1 #include2 using namespace std; 3 4 class person 5 { 6 public: 7 person() 8 { 9 puts("默认构造函数调用");10 }11 12 // person(const person &p)13 // {14 // m_age = p.m_age; 默认拷贝构造函数会执行这里,把所有值属性拷贝 15 // puts("拷贝构造函数调用");16 // }17 18 person(int age)19 {20 m_age = age;21 puts("有参构造函数调用");22 }23 24 ~person()25 {26 puts("析构函数调用");27 }28 29 int m_age;30 };31 32 void test()33 {34 person p;35 p.m_age = 18;36 person p2(p);37 cout << p2.m_age << endl; 38 }39 40 void test01()41 {42 person p(22);43 person p2(p);44 cout << p2.m_age << endl;45 } 46 int main()47 {48 //test();49 test01();50 return 0;51 }
关于第二个规则,如果你可以把除了拷贝构造函数的其他构造函数去掉,你运行是报错的
说明如果用户定义了拷贝构造函数,编译器将不会提供其他构造函数