我有一个关于好的C++风格的问题:我想写一个" MyClass“类,它有一个或多个指针作为成员,并且MyClass能够为这个指针分配内存。我想使用隐式的给出默认复制构造函数(以及默认赋值运算符)来复制MyClass的一个实例,以便只复制指针,并且新对象共享初始对象分配的数据。
我的想法是禁止复制的对象(使用复制构造函数或赋值操作符创建)释放内存(以及为成员指针分配内存)。为了区分复制对象和原始对象(由构造函数创建),我想使用以下代码:
class MyClass
{
public:
MyClass(): originalPtr(this) { data = new char[100000]; }
~MyClass() { if(originalPtr == this) delete[] data; }
private:
MyClass *originalPtr;
char *data; // shared data (not copiable)
char otherFeatures[10]; // individual data (copiable)
};这种解决方案(使用与this-pointer的比较)对于这样的目的(例如,通过值调用来解析对象)来说是一种好的风格,还是有风险?当然,我假设原始对象的寿命总是比复制的对象长。
谢谢!
发布于 2015-07-21 18:27:59
不,这不是个好主意。如果指针被多个实例共享,那么要释放的指针应该是最后一个死掉的指针,而不是原来的那个。这一点的不同之处在于,原来的那个可能不会死,这会导致所有其他人都指向垃圾。即使你假设它是最后一个死亡的类,你也需要意识到一个类的内部工作不应该依赖于外部假设。也就是说,类不能保证其生命周期如何由实现的其余部分管理,因此它不应该做假设。
在这种情况下,您应该跟踪对数据的引用。基本的想法是跟踪你有多少个类的副本。一旦该计数达到零,您就可以自由释放该内存;最后一个副本已经死了。你很幸运,STL already provides such an implementation。这些被称为Smart Pointers。还有其他的,比如std::unique_ptr,它通过确保数据只由单个实例拥有而实现了相反的效果。
发布于 2015-07-21 19:11:55
好的,假设一般情况下,原始对象最终不会死亡。我喜欢只计算实例的想法。例如,可以使用这样的概念:
class MyClass
{
public:
MyClass(): countOfInstances(new int())
{
++*countOfInstances;
data = new char[100000];
}
~MyClass()
{
--*countOfInstances;
if(!countOfInstances)
{
delete[] data;
delete countOfInstances;
}
}
MyClass(const MyClass &other) // analogous for the assignment operator
{
countOfInstances = other.countOfInstances;
data = other.data;
otherFeatures = other.otherFeatures;
++*countOfInstances;
}
private:
int *countOfInstances;
char *data; // shared data (not copiable)
char otherFeatures; // individual data (copiable)};
在这里,在允许复制之前,还应该确保共享内存已完全分配。
https://stackoverflow.com/questions/31536303
复制相似问题