拷贝构造函数是一种特殊的构造函数, 函数的名称必须和类名称一致, 它的唯一的一个参数是本类的一个引用变量, 该参数是 const 类型, 不可变的. 例如: 类 A 的拷贝构造函数的形式为 A(A& x). 当用一个已经初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候, 拷贝函数就会被自动调用. 也就是说, 当类的对象需要拷贝时, 拷贝构造函数将会被调用. 以下情况会自动调用拷贝构造函数:
1, 一个对象以值传递的方式传入函数体
2, 一个对象以值传递的方式从函数返回, 如下:
- #include <iostream>
- using namespace std;
- class B
- {
- public:
- B(){cout<<"构造函数 B"<<endl;}
- B(int i):data(i){cout<<"构造函数 B"<<" "<<data<<endl;}
- B play(B b){return b;}
- ~B(){cout<<"析构函数 B"<<endl;}
- private:
- int data;
- };
- int main()
- {
- B temp;
- temp.play(5);
- return 0;
- }
- View Code
3, 一个对象需要通过另一个对象进行初始化
如果在类中没有显示地声明一个拷贝构造函数, 那么编译器会自动生成一个默认的拷贝构造函数, 该构造函数完成对象之间的拷贝. 自定义拷贝构造函数是一种良好的编程风格, 它可以阻止编译器形成默认的拷贝构造函数, 提高源码效率.
深拷贝和浅拷贝:
在某些情况下, 类内成员变量需要动态开辟堆内存, 如果实行位拷贝 (位拷贝又称浅拷贝), 也就是把对象里面的值完全复制给另一个对象, 如 A=B. 这时, 如果 B 中有一个成员变量指针已经申请了内存, 那 A 中的那个成员也指向同一块内存. 这就出现了问题: 把 B 内存释放了, 这时 A 内的指针就是野指针了, 出现运行错误.
深拷贝和浅拷贝可以简单理解为: 如果一个类拥有资源, 当这个类的对象发生复制过程的时候, 资源重新分配, 这个过程就是深拷贝, 反之没有重新分配资源就是浅拷贝.
浅拷贝:
- #include <iostream>
- #include <string.h>
- using namespace std;
- class Example
- {
- private:
- int a;
- char *str;
- public:
- Example()
- {
- cout<<"调用构造函数"<<endl;
- }
- ~Example()
- {
- cout<<"调用析构函数"<<endl;
- }
- Example(int b)
- {
- a=b;
- cout<<"调用构造函数"<<endl;
- }
- Example(const Example& example)// 自定义拷贝构造函数
- {
- a=example.a;
- }
- void show()
- {
- cout<<a<<endl;
- }
- };
- int main()
- {
- Example a1(10);
- Example a2=a1;
- a2.show();
- return 0;
- }
输出:
调用构造函数
10
调用析构函数
调用析构函数
深拷贝:
- #include <iostream>
- #include <string.h>
- using namespace std;
- class Example
- {
- private:
- int a;
- char *str;
- public:
- Example()
- {
- cout<<"调用构造函数"<<endl;
- }
- ~Example()
- {
- delete str;
- cout<<"调用析构函数"<<endl;
- }
- Example(int b,char* e_str)
- {
- a=b;
- str=new char[b];
- strcpy(str,e_str);
- cout<<"调用构造函数"<<endl;
- }
- Example(const Example& example)// 自定义拷贝构造函数
- {
- a=example.a;
- str=new char[a];// 深拷贝
- if(str!=0)
- strcpy(str,example.str);
- }
- void show()
- {
- cout<<str<<endl;
- }
- };
- int main()
- {
- Example a1(10,"Hello");
- Example a2=a1;
- a2.show();
- return 0;
- }
输出:
调用构造函数
Hello
调用析构函数
调用析构函数
参考地址: https://www.cnblogs.com/BlueTzar/articles/1223313.html
来源: http://www.bubuko.com/infodetail-2687900.html