6 回答
TA贡献1842条经验 获得超12个赞
基本上如果你有一个析构函数(不是默认的析构函数),这意味着你定义的类有一些内存分配。假设该类在某些客户端代码之外或由您使用。
MyClass x(a, b); MyClass y(c, d); x = y; // This is a shallow copy if assignment operator is not provided
如果MyClass只有一些原始类型成员,则默认赋值运算符可以工作,但如果它有一些指针成员和没有赋值运算符的对象,则结果将是不可预测的。因此我们可以说如果在类的析构函数中有删除的东西,我们可能需要一个深度复制操作符,这意味着我们应该提供一个复制构造函数和赋值操作符。
TA贡献1797条经验 获得超6个赞
我什么时候需要自己申报?
三法则规定如果你宣布任何一个
复制构造函数
复制赋值运算符
析构函数
那么你应该宣布这三个。它源于这样的观察,即接管复制操作的意义的需要几乎总是源于执行某种资源管理的类,并且几乎总是暗示
在一个复制操作中进行的任何资源管理可能需要在另一个复制操作中完成
类析构函数也将参与资源的管理(通常是释放它)。要管理的经典资源是内存,这就是为什么管理内存的所有标准库类(例如,执行动态内存管理的STL容器)都声明“三大”:复制操作和析构函数。
规则三的结果是,用户声明的析构函数的存在表明简单的成员明智副本不太可能适合于类中的复制操作。反过来,这表明如果一个类声明了一个析构函数,那么复制操作可能不应该自动生成,因为它们不会做正确的事情。在采用C ++ 98时,这种推理的重要性并未得到充分认识,因此在C ++ 98中,用户声明的析构函数的存在对编译器生成复制操作的意愿没有影响。在C ++ 11中仍然如此,但仅仅因为限制生成复制操作的条件会破坏过多的遗留代码。
如何防止复制对象?
将复制构造函数和复制赋值运算符声明为私有访问说明符。
class MemoryBlock
{
public:
//code here
private:
MemoryBlock(const MemoryBlock& other)
{
cout<<"copy constructor"<<endl;
}
// Copy assignment operator.
MemoryBlock& operator=(const MemoryBlock& other)
{
return *this;
}
};
int main()
{
MemoryBlock a;
MemoryBlock b(a);
}
在C ++ 11及更高版本中,您还可以声明复制构造函数和赋值运算符已删除
class MemoryBlock
{
public:
MemoryBlock(const MemoryBlock& other) = delete
// Copy assignment operator.
MemoryBlock& operator=(const MemoryBlock& other) =delete
};
int main()
{
MemoryBlock a;
MemoryBlock b(a);
}
- 6 回答
- 0 关注
- 597 浏览
添加回答
举报