关于C++浅拷贝的问题
-
03-07-2019 - |
题
假设我有一个结构体“s”,带有一个 int 指针成员变量“i”。我在 s 的默认构造函数中为 i 分配了堆内存。稍后在代码的其他部分中,我将 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;
};
不用说,这是一个很大的痛苦,并且有很多微妙之处需要纠正。我什至不确定我是否在这里做过这件事,而且我已经做过几次了。不要忘记您必须复制所有成员 - 如果您稍后添加一些新成员,请不要忘记将它们也添加进来!
在类中将复制构造函数和operator=设为私有。 这就是“锁门”的解决方案。它简单而有效,但有时保护过度。
class A : public boost::noncopyable
{
...
};
切勿使用原始指针。 这既简单又有效。这里有很多选择:
- 使用字符串类而不是原始字符指针
- 使用 std::auto_ptr、boost::shared_ptr、boost::scoped_ptr 等
例子:
// 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
指针,但 i
指针都有
不隶属于 StackOverflow