c++ - 在这个例子中是否需要重载的 operator= ?

标签 c++

<分区>

Possible Duplicate:
What is The Rule of Three?

人们说,如果你需要一个析构函数,那么你实际上需要一个重载的 operator=

struct longlife{ };
class z
{
 z(){};
 ~z(){ for( auto it=hold.begin();it!=hold.end() ++it ) delete(*it); };
 vector<longlife*> hold;
};

假设在hold 上插入的所有指针都是堆分配的,为什么在这个例子中除了解构函数还需要其他东西?

任何其他我的意思是,

z& operator=( const z&ref )
{
 hold = ref.hold;
 return *this;
}

会:

z a;
a.hold.push_back( heap_item );
z a2;
a2 = a;

导致内存泄漏?有时很难理解为什么三的规则是规则

最佳答案

不仅需要赋值运算符,还需要实现拷贝构造函数。否则,编译器将提供默认实现,这将导致两个拷贝(在赋值/复制构造之后)包含指向相同 longlife 实例的指针。然后,两个拷贝的析构函数将删除这些导致未定义行为的实例。

z a;
a.hold.push_back( heap_item );
z a2;
a2 = a;

a.hold[0]a2.hold[0] 都包含指向相同heap_item 的指针;从而在销毁过程中造成双重删除。

避免必须实现赋值运算符和复制构造函数的简单方法是使用智能指针将 longlife 实例保存在 vector 中。

std::vector<std::unique_ptr<longlife>> hold;

现在甚至不需要为您的类编写析构函数。


对于 C++03,您的选择是使用 std::tr1::shared_ptr(或 boost::shared_ptr)而不是 unique_ptr 或使用 boost::ptr_vector (当然,这也是 C++11 的一个选项)而不是 std::vector

关于c++ - 在这个例子中是否需要重载的 operator= ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12828091/

相关文章:

c++ - 使 QWidget 透明

c++ - 使用 Xcode 调试我的代码 C++

c++ - 运行时进程名称更改 (C++)

c++ - 元编程成员检查器不适用于返回具有基类的类型的函数成员

c++ - 我该怎么做才能让我的代码寻找最少数量的硬币?

c++ - 类和数组

c++ - 库 c++ 的接口(interface)

c++ - Flutter Desktop : How to handle Native Code editing in an IDE (Intellisense, 自动完成等)?

c++ - 知道 QObject 名称是否已更改的最佳方法是什么

c++ - Visual Studio 2019 : How to use Platform Toolset v140_xp?