我的代码如下,基本上我正在使用一些外部库并将这个库中的一些类对象嵌入到myClass中,然后用OBJ做事,
#include "extern_lib.h" //some library
class myClass
{
public:
extern_class *obj1;
extern_class *obj2;
double arr[3];
};
int main()
{
myClass *OBJ= new myClass();
OBJ->obj1 = new extern_class(arg1...);
OBJ->obj2 = new extern_class(arg2...);
//do something like
OBJ->obj1->extern_fun1(arg1...);
OBJ->obj2->extern_fun2(arg2...);
//delete
delete OBJ;
return 0;
}
我想知道,
1-为了释放所有对象,是否足以删除OBJ?
2-是否有更好的方法来编写此代码?
答案 0 :(得分:3)
delete
致电new
。std::unique_ptr
或更好的智能指针,使用RAII。为了澄清这一点:智能指针和RAII甚至不仅仅是更好的方式,它们是 在现代C ++中正确执行它的方式。以下是 RAII :
的充分示例#include "extern_lib.h"
class myClass
{
public: // note that public members are possibly bad design (depending on your situation)
extern_class obj1;
extern_class obj2;
double arr[3];
};
int main()
{
myClass foo;
foo.obj1.extern_fun(arg1...);
foo.obj2.extern_fun(arg2...);
return 0;
}
请注意,在任何情况下都无法使用RAII。如果遇到这种情况,请按照说明使用智能指针:
#include "extern_lib.h"
class myClass
{
public: // note that public members are possibly bad design (depending on your situation)
std::unique_ptr<extern_class> obj1;
std::unique_ptr<extern_class> obj2;
double arr[3];
};
int main()
{
myClass foo;
foo.obj1 = std::unique_ptr<extern_class>(new extern_class(arg1...));
foo.obj2 = std::unique_ptr<extern_class>(new extern_class(arg2...));
foo.obj1->extern_fun(arg1...);
foo.obj2->extern_fun(arg2...);
return 0;
}
答案 1 :(得分:2)
为了释放所有对象,删除OBJ是否足够?
不会,这会产生资源泄漏,因为myClass
的(默认)析构函数不关心删除指针成员。
有更好的方法来编写此代码吗?
是的,使用智能指针。例如:
class myClass
{
public:
std::unique_ptr<extern_class> obj1;
std::unique_ptr<extern_class> obj2;
double arr[3];
};
通常,尝试按类创建资源拥有。也就是说,在构造函数中分配它们并在析构函数中释放它们。标准库的智能指针已经为您完成了这项工作。避免在单个类中管理多个资源。
顺便说一句:如果你的例子没有做作,而你根本就没有使用多态,那么只需要删除所有new
并简单地使用具有自动存储持续时间的变量。 C ++不是Java。
更新:如果不需要多态性,这是(一种方法)如何摆脱new
:
class myClass
{
public:
extern_class obj1;
extern_class obj2;
double arr[3];
myClass(type arg1a, ..., type arg2a, ...) : obj1(arg1a, ...), obj2(arg2a, ...)
// ^^^^ member initializer list ^^^^
{
}
};
关键是通过使用所谓的成员初始化列表来创建成员对象,作为创建myClass
的过程的一部分。如果您正在编写C ++ 11,则更喜欢编写obj1 {arg1a, ...}, obj2 {arg2a, ...}
以保持一致性。 (然而,旧的语法仍然可以正常工作。)
同样在main
函数中:
int
main()
{
myClass mc(arg1a, ..., arg2a, ...); // (1)
mc.obj1.extern_func(...);
mc.obj2.extern_func(...);
return 0; // (2)
}
在第(1)行,我们使用我们的新构造函数在堆栈上创建myClass
的实例,该构造函数将正确创建成员obj1
和obj2
。 myClass
的编译器生成的默认构造函数将正确地破坏mc.obj1
和mc.obj2
,因为mc
超出了第(2)行的范围。同样,在C ++ 11中,第1行(1)可以更加干净地编写为myClass mc {arg1a, ..., arg2a, ...};
。