在设计一个动态分配内存的类时,我遇到了有关内存分配的以下问题。我希望你们中的一些人能够指出我如何以更好的方式设计课程。我的类动态分配内存,因此也会在析构函数中删除它。
为了说明问题,请考虑以下愚蠢的类声明:
class testClass{
int* data;
public:
testClass(){
data = new int;
*data = 5;
}
~testClass(){
delete data;
}
};
到目前为止一切顺利。现在假设我在main
中创建了其中一个对象int main(){
testClass myObject;
return 0;
}
当然还没有问题。但是,假设我现在编写一个函数,它将testClass对象作为输入并从main调用它。
void doNoting(testClass copyOfMyObject){
//do nothing
}
int main(){
testClass myObject;
doNothing(myObject);
return 0;
}
这一次,该函数创建了一个局部变量copyOfMyObject,它只是myObject的一个副本。然后,当到达该函数的末尾时,该本地对象自动调用其析构函数,该析构函数删除其数据指针指向的内存。但是,由于这是myObject的数据指针所指向的相同内存,因此myObject在过程中无意中删除了其内存。我的问题是:什么是设计课程的更好方法?
答案 0 :(得分:6)
当您致电doNothing()
时,它正在复制您的testClass
对象,因为它是按值传递的。不幸的是,当这个副本被销毁时,它会调用析构函数,它会删除原始data
实例使用的testClass
。
您想要了解"复制构造函数"和"通过引用"传递。也就是说,您应该为您的类定义一个复制构造函数,以便在复制一个实例时,它为其data
成员分配自己的内存。此外,您可以将指针或引用传递给doNothing()
,而不是通过值传递,这样就不会复制。
答案 1 :(得分:2)
您应该创建一个复制构造函数,它是表单的构造函数:
testClass::testClass(const testClass &o)
{
// appropriate initialization here
}
在您的情况下," 适当的初始化"可能意味着分配一大块内存并将内存从旧块复制到新块中。或者它可能意味着做引用计数。或者其他什么。
您还应该在StackOverflow上阅读有关Rule of Three的更多信息!
答案 2 :(得分:0)
以下是来自authority的指南:任何{析构函数,赋值运算符,复制构造函数}的类通常都需要全部
您需要一个复制构造函数,它将为您的数据创建一个新的已分配的int,然后将其破坏,但不会影响原始。
或者,你可以创建一个空白的私有拷贝构造函数,它可以有效地禁用它,强制你的用户通过引用传递,或者另一种非复制的处理方式。