假设我有一个带有int指针成员变量“i”的结构“s”。我在s的默认构造函数中为i分配内存。稍后在代码的其他部分中,我将一个s值的实例传递给某个函数。我在这里做一个浅色的副本吗?假设我没有为s实现任何复制构造函数或赋值运算符或任何东西......只是默认的构造函数。
答案 0 :(得分: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;
};
毋庸置疑,这是一个重大的痛苦,并且有很多细微之处可以做到。我甚至都不确定我是在这里做到的,而且我已经完成了几次。不要忘记你必须复制所有成员 - 如果你以后添加一些新成员,也不要忘记添加它们!
在您的班级中创建复制构造函数和operator = private。这是“锁门”解决方案。它简单有效,但有时过度保护。
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)
{
}
};
答案 1 :(得分:5)
是的,这是一份浅薄的副本。您现在有两个s副本(一个在调用者中,一个在堆栈中作为参数),每个副本都包含指向同一块内存的指针。
答案 2 :(得分:2)
您将拥有s
结构的两个副本,每个副本都有自己的i
指针,但两个i
指针都具有指向同一地址的相同值。记忆 - 所以是的,这将是一个浅薄的副本。