内存管理 - 有关C++中浅拷贝的问题
memory management - Question about shallow copy in C++
假设我有一个带有整数指针成员变量"i"的结构"s"。 我在 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;
};
不用说,这是一个主要的痛苦,有很多微妙之处需要纠正。我什至不完全确定我在这里做了,我已经做过几次了。不要忘记您必须复制所有成员 - 如果您稍后添加一些新成员,请不要忘记添加它们!
在类中将复制构造函数和运算符 = 设为私有。这就是"锁门"解决方案。它简单有效,但有时过度保护。
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
指针将具有指向内存中相同地址的相同值 - 所以是的,它将是一个浅副本。
相关文章:
- 与浅拷贝构造函数和深拷贝构造函数混淆
- 使用复制构造函数修复浅拷贝
- C++ 一个lambda浅拷贝const Type&如果它被赋予一个命名捕获,如[copy=val](){}?
- 在构造函数中浅拷贝字符串数组
- 为什么移动语义与动态 mem 分配中的浅拷贝具有相同的行为
- 在函数中传递带有指针成员的结构是浅拷贝或深拷贝在 C 中
- C++ 如何为地图创建浅拷贝构造函数
- 浅拷贝到协议缓冲区的字节字段中
- C++ 标准::字符串意外更改。我认为这个问题是关于深和浅拷贝的
- 为什么下面的类不对数组 arr 进行浅拷贝?
- 在C++中使用浅拷贝而不是引用的原因
- C++需要一个浅拷贝,但并不完全如此
- STD向量C++ - 深拷贝或浅拷贝
- 浅拷贝后追加字符指针
- 带矢量的浅拷贝
- 康斯特指针浅拷贝
- 从一个数组到另一个数组的选择性浅拷贝
- 静态内存分配中的浅拷贝构造函数问题
- 是否vector::push_back()进行浅拷贝&如何解决这个问题
- 内存管理 - 有关C++中浅拷贝的问题