`

条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

阅读更多
条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

这是非常重要的一条,经常会导致一些内存的泄露,如以下这段代码所示:
// 一个很简单的string类
class string {
public:
  string(const char *value);
  ~string();

  ...                           // 没有拷贝构造函数和operator=

private:
  char *data;
};

string::string(const char *value)
{
  if (value) {
    data = new char[strlen(value) + 1];
    strcpy(data, value);
  }
  else {
    data = new char[1];
    *data = '\0';
  }
}
inline string::~string() { delete [] data; } //还是会产生一个函数的地址
来看看在 没有拷贝构造函数和operator=的情况,
最简单的:
string a("hello");
string b("world");
b=a;
如果没有拷贝构造函数,系统会默认进行一对一的赋支,那么b中的char指针数据就丢失了。

另外一种情况,如果离开了它的生存空间被系统析构
string a("hello");                 // 定义并构造 a

{                                  // 开一个新的生存空间
  string b("world");               // 定义并构造 b

  ...

  b = a;                           // 执行 operator=,
                                   // 丢失b的内存

}                                  // 离开生存空间, 调用
                                   // b的析构函数
string c = a;                      // c.data 的值不能确定!
                                   // a.data 已被删除
delete c // delete a;

那么不难想到,像这样被系统析构掉的还有一种情况就是传值
void donothing(string localstring) {}
那么这个函数退出时,localstring就被析构,牵连到的还有原来的值

effectiv给出一个比较均衡的方法是可以用比较复杂的计数,来跟踪当前数据结构;或者对一些花费代价

比较大的类里,将拷贝和构造设置成私有的函数

在写法上可以将拷贝和赋值写在一起
比如
string& string::operator=(const string& rhs)
{
//do...
}


string::YourClass(string &str)
{
  *this=str;//调用赋值函数
}
0
0
分享到:
评论

相关推荐

    Effective.C++.中文第二版.50条款doc文档.chm

    条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符 条款12: 尽量使用初始化而不要在构造函数里赋值 条款13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同 条款14: 确定基类有虚析构...

    Effective_C++

    **条款11:为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符** - **目的**: 确保正确的复制行为。 - **解释**: 对于含有动态分配内存的类,应该显式定义拷贝构造函数和赋值操作符,以便在复制对象时...

    高效C++:从C到C++

    **条款11:为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符** - **背景**:当类中包含动态分配的资源时,拷贝构造函数和赋值操作符需要正确实现以避免浅拷贝问题。 - **原因**:如果不正确实现这些...

    Effective C++

    8. **为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符**: 拷贝构造函数用于创建对象的副本,赋值操作符用于将一个对象的值复制到另一个对象。对于包含动态分配内存的类,这两个函数必须正确处理内存...

    effecitve C++(中文版)

    条款11阐述了对于涉及动态内存的类,应提供拷贝构造函数和赋值操作符,以确保正确复制和赋值。条款12建议在构造函数中优先使用初始化列表,而不是在函数体内部赋值,以减少未定义行为的可能性。条款13指出,初始化...

    effective c++ 第三版 高清 带书签

    C++编译器会为类提供默认的构造函数、拷贝构造函数、赋值运算符以及析构函数等成员函数。然而,如果类中有动态分配的内存或需要进行深拷贝时,程序员需要自行实现这些成员函数。条款5讨论了这些默认行为,并给出了...

    Effective C++.doc

    条款11指出需要动态分配内存的类应有拷贝构造函数和赋值操作符,以确保正确复制。条款12强调初始化优于赋值,条款13规定初始化列表应按照成员声明的顺序进行。条款14建议基类有虚析构函数以支持多态销毁。条款15和16...

    Effetive+STL(Word文档)

    - 容器中的元素应当具备高效的拷贝构造函数和赋值运算符。 - 需要特别注意拷贝成本较高的类型。 - **条款4:使用`empty()`代替检查`size()`是否为0** - `empty()`函数更加直观且通常更高效。 - 这是因为`empty...

    effective stl stl 技巧

    - 当容器存储的是自定义类型时,确保该类型的拷贝构造函数和赋值操作符实现得高效且无泄漏。 #### 条款4:用empty来代替检查size()是否为0 - **核心概念**:`empty()`方法提供了更直观的方式来判断容器是否为空。...

    高质量c++(内含面试题)

    - **拷贝构造函数与赋值函数**:实现拷贝构造函数和赋值操作符以支持深拷贝。 - **派生类中的基本函数实现**:在派生类中正确实现构造函数、析构函数和赋值操作符。 #### 十、类的继承与组合 - **继承**:了解继承...

    Effetive STL中文版

    - **条款3**:确保容器内对象的拷贝构造函数和赋值操作符高效且正确实现。 - **条款4**:使用`empty()`函数代替检查`size()`是否为0,因为前者更简洁且通常更快。 - **条款5**:优先使用区间成员函数,如`std::...

    EffectiveC++终稿44__tagged_2019-06241

    - **了解C++默默编写并调用哪些函数**: C++会自动生成默认构造函数、拷贝构造函数、赋值运算符和析构函数,理解这些函数的作用是必要的。 - **明确拒绝编译器自动生成的函数**: 当不希望使用这些默认函数时,应...

    Addison.Wesley.Effective.CPP.3rd.Edition.May.2005.pdf

    书中还强调了构造函数、析构函数、赋值操作符和拷贝构造函数的正确使用方法,这些都是C++中实现自定义类型时的关键点。 作者还讨论了设计模式在C++中的应用,比如工厂模式、单例模式等,这些都是面向对象设计中常用...

    构造函数定义为private或者protected的好处

    将拷贝构造函数和赋值操作符重载设为`private`但不提供实现是一种常见做法,这通常称为“禁用拷贝构造函数和赋值操作符”。《Effective C++》中的条款27对此有详细的解释。 4. **封装与安全**:将构造函数设为`...

    Effective C++ 第三版.pdf

    应当使用深拷贝(而非浅拷贝),并且当类中包含指向动态分配内存的指针时,必须自定义复制构造函数和赋值操作符。此外,当不再需要对象时,析构函数会自动调用,但当对象是通过new得到指针时,程序员必须手动调用...

Global site tag (gtag.js) - Google Analytics