2014-09-12 122 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