如果我有以下示例:
test.h
class MyClass
{
public:
MyClass();
std::string name1;
std::string name2;
std::string type1;
std::string type2;
void method1(MyClass &obj1);
void method2(MyClass &obj2);
}
TEST.CPP
MyClass *mainObject = new MyClass();
MyClass::MyClass()
{
}
void MyClass::method1((MyClass &obj1)
{
//do stuff
mainObject=&obj1; //we populate some of the MyClass variables
}
void MyClass::method2((MyClass &obj2)
{
//do stuff
mainObject=&obj2; //we populate the rest of MyClass variables
}
我什么时候应该删除test.cpp中的mainObject?我应该创建一个析构函数,以便客户端删除它吗?
答案 0 :(得分:4)
这是一个很好的例子,最好通过自己不考虑来解决。
使用shared_ptr<MyClass> mainObject;
(新的C ++ 11或Boost版本)。它会为你做delete
。
请注意,method1()
和method2()
也应该通过shared_ptr
进行论证。目前,他们做了一件非常糟糕的事情:删除一个通过引用传递的对象。
答案 1 :(得分:2)
多次删除指针变量(指向非0)比不删除它更糟糕。因为前者可能导致很难发现错误和未定义的行为。
您的代码编写不正确。您尝试使用delete mainObject;
或&obj1
分配时{1}}。但请确保您只是第一次这样做。如果指针指向&obj2
或delete
,请不要obj1
。
我从这个问题和你的previous question感觉到你来自Java / C#背景。最好先阅读一本关于C ++的好书,你将了解大多数时候你不需要obj2
。
答案 2 :(得分:1)
完成使用指向的对象后,应该删除指针。在指向单个对象时,不应删除指针两次。如果指针指向未使用new
动态分配的对象,则不应删除该指针。
答案 3 :(得分:0)
应始终存在任何资源的逻辑所有者,该所有者应删除该资源。
有些情况下共享所有权是有意义的,这就是boost::shared_ptr
和类似解决方案的用途。放弃所有权的最后一个是删除资源的那个。
答案 4 :(得分:0)
我什么时候应该删除test.cpp中的mainObject?
不再使用时。
我应该创建一个析构函数,以便客户端删除它吗?
如果必须释放MyClass类的某些资源,则只需要创建析构函数 - 显示的代码不是这种情况。你应该释放的那个(=删除)是mainObject。但无论如何,method1(..)和method2(..)正在覆盖导致悬空指针的mainObject指针(你不能再到达对象)。
[编辑]
回答你的问题:
可以多次删除指针c ++?
delete
”答案是否定的,将导致UB。指针为零的delete
已定义且合法。答案 5 :(得分:0)
从所有评论中看起来您可能真的想要以下内容:
static MyClass mainObject; // Not a pointer. Local to test.cpp
void MyClass::method1()
{
//do stuff
mainObject=*this; // Make a copy of the last object modified.
}
void MyClass::method2()
{
//do stuff
mainObject=*this; // Make a copy of the last object modified.
}
通过这种方式,无论您拨打foo.method1()
还是bar.method2
,.
左侧的对象都会被复制到mainObject
。根本不需要指针时髦,没有new
和没有delete
。
答案 6 :(得分:0)
我认为我会采用稍微不同的方式。
像这样:
test.h
class MyClass
{
public:
MyClass();
std::string name1;
std::string name2;
std::string type1;
std::string type2;
void method1(MyClass &obj1);
void method2(MyClass &obj2);
}
TEST.CPP
MyClass mainObject; // default c-tor called automatically.
MyClass::MyClass()
{
}
void MyClass::method1(MyClass & obj1)
{
//do stuff
//we populate some of the MyClass variables
mainObject.name1=obj1.name1;
mainObject.type1=obj2.type1;
}
void MyClass::method2(MyClass & obj2)
{
//do stuff
//we populate more of the MyClass variables
mainObject.name2=obj1.name2;
mainObject.type2=obj2.type2;
}
没有简单的方法只填充部分对象而不指定哪些部分。
但是,否则,如果你不使mainObject成为指针,那么你不需要为它分配空间,这是自动完成的。 (但是,我应该反对使用全局变量,除非它们真的需要!)
我认为你想要做的事情的这个实现将完全避免使用堆的需要,不需要新的/删除。