本文用Markdown编辑,这里对Markdown的支持不完善,更好的阅读体验请移步:我的Markdown文本
C++三大函数:
- 析构函数
- 复制构造函数
- operator=
析构函数
函数模样:~S()
当一个对象超出作用域或执行delete的时候,析构函数就被调用。
复制构造函数
函数模样:S(const S& s)
以下情况,复制构造函数均会被调用:
-
声明的同时初始化:
S s1 = s2; //注意此时虽然出现=,但是不是调用operator=哦 S s1(s2);
-
调用函数时使用按值传递(而不是按引用传递)
void f(S s); S s1; f(s1);
-
通过值返回对象
S f() { S s1; return s1; }
operator=
函数模样:const S& operator=(const S& s)
当=应用于两个已经构造的对象时,就调用复制赋值运算符operator=。
S s1;
s1 = s2; //注意与S s1 = s2; 的区别
注意事项:
-
三大函数不手动实现的时候,会使用默认的版本。比如operator=的默认版本会依次为数据成员复制,如果是基本数据类型自然没什么问题,但当数据成员含有指针的时候,operator的只会进行
浅复制
,即只是指针本身被复制,而不是指针所指向的内容被复制。见下例。class S { public: int *p; S(int x=0){p=new int(x);} }; void f() { S s1(2), s2; S s3 = s1; s2 = s1; *s1.p=3; cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl;//3 3 3 }
很明显这不是我们想要的,我们想让不同的对象的值不互相影响,此时需要实现
深复制
,见下例。class S { public: int *p; S(int x=0){p=new int(x);} S(const S& rhs) { p = new int(*rhs.p); } const S& operator=(const S& rhs) //rhs=right-hand side { if (this != &rhs) //检查是否复制自身 *p = *rhs.p; return *this; } }; void f() { S s1(2), s2; S s3 = s1; s2 = s1; *s1.p=3; cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl; //3 2 2 }