2014-09-12 86 views
1

我的代码是像下面,基本上我使用一些外部库,并嵌入了一些类对象,从这个库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-是否有更好的方法来编写此代码?

回答

2

为了释放所有的对象,它足以删除OBJ?

不,这会产生资源泄漏,因为myClass的(默认)析构函数并不在乎删除指针成员。

有没有更好的方法来写这段代码?

是的,使用智能指针。例如:

class myClass 
{ 
public: 
    std::unique_ptr<extern_class> obj1; 
    std::unique_ptr<extern_class> obj2; 
    double arr[3]; 
}; 

一般情况下,尝试使类国有资源。也就是说,在构造函数中分配它们并在析构函数中释放它们。标准库的智能指针已经为你做好了这项工作。避免在单个类中管理多个资源。顺便说一句:如果你的例子没有被设计出来,而且你根本没有使用多态性,那么只需要去除所有那些news,并简单地使用具有自动存储持续时间的变量。 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一个实例,它将正确创建成员obj1obj2。编译器生成的默认构造函数myClass将正确地破坏mc.obj1mc.obj2,因为mc超出第(2)行的作用域。再次,在C++ 11行(1)可以写得更干净如myClass mc {arg1a, ..., arg2a, ...};

+0

对不起,我是新来的C++,但如果我不使用“新”,与“extern_class obj1;”与“OBJ-> obj1 = extern_class(arg1 ...);”它不工作,基本上我需要根据arg1首先初始化obj1。也许我错了... – lorniper 2014-09-12 22:45:22

+0

不知道你可能得到错误。我的代码示例编译是否提供了'extern_class'和'extern_func'的适当声明(当然,重命名'type'并删除省略号)。也许问一个新问题? – 5gon12eder 2014-09-14 13:49:56

+0

现在它的作品,谢谢! – lorniper 2014-09-14 14:21:51

3
  1. 不,这是不够的。你必须打电话给delete,每个new明确地放在你的代码中。
  2. 使用智能指针如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; 
} 
+0

智能指针和RAII,你能给我一些简单的例子基于我的例子吗? – lorniper 2014-09-12 22:16:05

+0

为你添加它。请阅读评论。 – 2014-09-12 22:19:24

+0

我必须说我使用“OBJ-> obj1 = new extern_class(arg1 ...)”,因为obj1需要根据主函数中的一些参数进行初始化,所以你展示的RAII示例不适合? – lorniper 2014-09-12 22:42:11