Effective C++ 学习笔记11
2015-02-16 17:07
309 查看
条款11:为需要动态分配内存的类(含有指针的类)声明一个拷贝构造函数呃一个赋值操作符
请注意下面这段代码:
1.b.data和a.data指向了同一块内存,由于程序结束时,对象a和对象b都会调用各自的析构函数,导致一块相同的内存被释放了两次;
2.对象b.data指向的内存不会被删除,产生了内存泄露(注:程序关闭时,内存会被系统回收)。
之所以产生上述问题,是因为调用了默认的operator=,该操作是对类的数据成员进行逐位拷贝(为了兼容C语言的struct),所以对指针来说,得到的是地址,而并非里面的内容。
默认的拷贝构造函数和默认的赋值运算符几乎会产生一样的问题。
请看下面一个关于默认的拷贝构造函数的例子:
当s作为实参传递到函数中时,调用的是默认的拷贝构造函数,当形参离开他的生存空间,就会释放s所占用的内存,然后s在离开它自己的生存空间时,就会报错,因为对象s的析构函数去delete一个已经delete的指针。
所以,为了避免此类情况,只要类里面有指针,我们就要写自己版本的拷贝构造函数和赋值运算符函数。
有时候,我们要禁止类的赋值运算,我们可以把自定义的operator=函数声明为私有函数,并且不去定义它,这样一来,程序只要一有该类的赋值运算,编译器就会有反应(注:如果你去实现了该函数,则该类的成员函数和类的友元一样可能会使用该函数)。
请注意下面这段代码:
#include <iostream> class String { public: String(const char* value) { if (value) { int length = strlen(value) + 1; data = new char[length]; memcpy(data, value, length); } else { data = new char[1]; data[0] = '\0'; } } ~String() { if (data) { delete[] data; } } private: char* data; }; int main() { String a("Hello"); String b("World!"); b = a; //默认operator= return 0; }以上这段代码会产生如下问题:
1.b.data和a.data指向了同一块内存,由于程序结束时,对象a和对象b都会调用各自的析构函数,导致一块相同的内存被释放了两次;
2.对象b.data指向的内存不会被删除,产生了内存泄露(注:程序关闭时,内存会被系统回收)。
之所以产生上述问题,是因为调用了默认的operator=,该操作是对类的数据成员进行逐位拷贝(为了兼容C语言的struct),所以对指针来说,得到的是地址,而并非里面的内容。
默认的拷贝构造函数和默认的赋值运算符几乎会产生一样的问题。
请看下面一个关于默认的拷贝构造函数的例子:
void doNothing(String localString) {} String s = "The Truth Is Out There"; doNothing(s);
当s作为实参传递到函数中时,调用的是默认的拷贝构造函数,当形参离开他的生存空间,就会释放s所占用的内存,然后s在离开它自己的生存空间时,就会报错,因为对象s的析构函数去delete一个已经delete的指针。
所以,为了避免此类情况,只要类里面有指针,我们就要写自己版本的拷贝构造函数和赋值运算符函数。
有时候,我们要禁止类的赋值运算,我们可以把自定义的operator=函数声明为私有函数,并且不去定义它,这样一来,程序只要一有该类的赋值运算,编译器就会有反应(注:如果你去实现了该函数,则该类的成员函数和类的友元一样可能会使用该函数)。
相关文章推荐
- Effective C++ 学习笔记(11)
- Effective C++ 学习笔记:让operator=返回*this的引用
- “Effective C++ Third Edition”学习笔记(一)
- Effective C++ 学习笔记(7)
- Effective C++ 学习笔记(13)
- Effective C++ 学习笔记(9)
- Effective C++ 学习笔记:避免public接口出现数据成员
- Effective C++ 学习笔记:关于继承
- Effective C++ 学习笔记(6)
- Effective C++ 学习笔记(1)
- Effective C++ 学习笔记(12)
- C++学习笔记(11)——虚函数的特性
- Effective Java 学习笔记 (11)
- “Effective C++ Third Edition”学习笔记(三)
- Effective C++ 学习笔记(1) : 语言联邦、弱化预编译器、const、初始化
- Effective Java 学习笔记 (11)
- Effective C++ 学习笔记:为含指针变量的类声明一个拷贝构造函数和一个赋值操作符
- more effective c++学习笔记 ---- 条款31
- “Effective C++ Third Edition”学习笔记(二)
- Effective C++ 学习笔记(8)