5

假设我有一个带有 int 指针成员变量“i”的结构“s”。我在 s 的默认构造函数中为 i 在堆上分配内存。稍后在代码的其他部分中,我将 s 的实例按值传递给某个函数。我在这里做浅拷贝吗?假设我没有为 s 实现任何复制构造函数或赋值运算符或任何东西......只是默认构造函数。

4

3 回答 3

8

跟进@[don.neufeld.myopenid.com] 所说的话,它不仅是一个浅拷贝,而且(随你选择)内存泄漏或悬空指针。

// memory leak (note that the pointer is never deleted)
class A
{
  B *_b;
  public:
  A()
  : _b(new B)
  {
  }
};

// dangling ptr (who deletes the instance?)
class A
{
  B *_b;
  public:
  A()
  ... (same as above)

  ~A()
  {
    delete _b;
  }
};

为了解决这个问题,有几种方法。

始终在使用原始内存指针的类中实现复制构造函数和 operator=。

class A
{
  B *_b;
  public:
  A()
  ... (same as above)

  ~A()
  ...

  A(const A &rhs)
  : _b(new B(rhs._b))
  {
  }

  A &operator=(const A &rhs)
  {
    B *b=new B(rhs._b);
    delete _b;
    _b=b;
    return *this;
};

不用说,这是一个主要的痛苦,并且有很多微妙之处要纠正。我什至不完全确定我是在这里做的,而且我已经做过几次了。不要忘记您必须复制所有成员 - 如果您稍后添加一些新成员,请不要忘记也添加它们!

Make the copy constructor and operator= private in your class. This is the "lock the door" solution. It is simple and effective, but sometimes over-protective.

class A : public boost::noncopyable
{
  ...
};

Never use raw pointers. This is simple and effective. There are lots of options here:

  • Use string classes instead of raw char pointers
  • Use std::auto_ptr, boost::shared_ptr, boost::scoped_ptr etc

Example:

// uses shared_ptr - note that you don't need a copy constructor or op= - 
// shared_ptr uses reference counting so the _b instance is shared and only
// deleted when the last reference is gone - admire the simplicity!
// it is almost exactly the same as the "memory leak" version, but there is no leak
class A
{
  boost::shared_ptr<B> _b;
  public:
  A()
  : _b(new B)
  {
  }
};
于 2008-10-19T07:51:24.170 回答
5

是的,这是一个浅拷贝。您现在有两个 s 副本(一个在调用者中,一个在堆栈中作为参数),每个副本都包含指向同一内存块的指针。

于 2008-10-19T07:10:45.470 回答
2

您将拥有该s结构的两个副本,每个副本都有自己的i指针,但两个i指针将具有指向内存中相同地址的相同值 - 所以是的,这将是一个浅拷贝。

于 2008-10-19T07:48:03.133 回答