繁体   English   中英

为什么以及何时应该在C ++中使用Copy Constructor? 为什么不鼓励浅拷贝呢?

[英]Why and when should use a Copy Constructor in C++? Why shallow copy is discouraged?

让我们说我们创建一个类Student的对象,我们创建两个实例/对象类Student(即StudentA和StudentB)。 我们使用浅层复制来初始化B的数据成员,如下所示:

学生B =学生A;

然后我们摧毁了StudentB。 我们在这里面临悬空指针的情况吗? 为什么以及如何? 请解释。

我们在这里面临悬空指针的情况吗? 为什么以及如何? 请解释。

这取决于学生的实施。 如果学生看起来像这样......

class Student
{
public:
  char* m_name;
  Student(const char* name)
  {
    m_name = new char[strlen(name)+1];
    strcpy(m_name,name);
  }
  ~Student()
  {
    delete[] m_name;
  }
};

...然后出现问题:当你复制一个学生时,你有两个指向相同m_name数据的指针,当两个学生实例被删除时,m_name数据被删除两次,这是非法的。 为避免该问题,Student需要一个显式的复制构造函数,以便复制的Student具有指向不同m_name数据的指针。

或者,如果学生看起来像这样......

class Student
{
public:
  std::string m_name;
  Student(const char* name)
    : m_name(name)
  {
  }
};

...然后没有问题,因为魔术(即显式复制构造函数)是在std :: string类中实现的。

总之,如果类包含分配和删除的指针,则需要显式复制构造函数(或者显式没有复制构造函数,但在任何一种情况下,不仅仅是默认构造函数)。

真的不鼓励浅层复制 - 这是一个知道什么时候合适的问题。

这里的问题是“所有权”之一。 “Student”类是否“拥有”指向的数据,因此负责(在其析构函数中)删除该数据。

基本上,如果您获取拥有某些指向数据的对象的浅表副本,然后销毁原始数据或副本,则删除指向数据(由析构函数删除)。 但是你仍然在对象中有一个没有被破坏的引用 - 一个悬垂的指针。

OTOH,如果对象不拥有指向的数据,析构函数不会删除指向的数据,并且没有问题。 虽然你必须确保某些东西拥有指向的数据,否则你会有内存泄漏。

跟踪指向数据的所有权是非垃圾收集语言(如C ++)的关键技能,并且是应用资源分配初始化模式的基础。

简单来说: 如果您的类成员变量包含它也拥有的指针。

另一点是成员的指向数据是不可变的。 通过使用引用计数智能指针在实例之间共享它是不可观察的。 例如,我有一些看起来像的代码

struct SizeContainer {
  // ... stuff ...
private:
  boost::shared_ptr<SizeExpression> p;
};

我没有声明复制构造函数和复制赋值运算符,因为无论如何都无法更改p ,因此可以跨多个实例共享它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM