假设我有一个结构体“s”,其中包含一个整型指针成员变量“i”。在s的默认构造函数中,我为i在堆上分配了内存。稍后在代码的其他部分,我通过值传递将s的实例传递给某个函数。这里我是在进行浅拷贝吗?假设我没有为s实现任何复制构造函数或赋值运算符或其他任何东西...只有默认构造函数。
假设我有一个结构体“s”,其中包含一个整型指针成员变量“i”。在s的默认构造函数中,我为i在堆上分配了内存。稍后在代码的其他部分,我通过值传递将s的实例传递给某个函数。这里我是在进行浅拷贝吗?假设我没有为s实现任何复制构造函数或赋值运算符或其他任何东西...只有默认构造函数。
为了跟进@[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;
}
};
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;
};
class A : public boost::noncopyable
{
...
};
永远不要使用裸指针。这很简单而且有效。有很多替代方案:
示例:
// 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)
{
}
};
是的,这是一次浅拷贝。现在你有两个s的副本(一个在调用者中,一个作为参数在堆栈中),它们都包含指向同一块内存的指针。
s
结构体的拷贝,每个拷贝都有自己的 i
指针,但是这两个指针的值指向内存中相同的地址 - 所以是一种浅拷贝。