2015-04-24 29 views
1

考慮下面的類爲類的指針數據成員處理動態內存?

class A 
{ 
     ClassF1 *ptrobjF1; 
     ClassF2 *ptrobjF2; 
     ClassF3 *ptrobjF3; 

     A() 
     { 
      ptrobjF1 = NULL; 
      ptrobjF2 = NULL; 
      ptrobjF3 = NULL; 
     } 
}; 

在上述A類,我有類ClassF1,ClassF2和ClassF3 3名指針數據成員。內存將在需要時分配給這個類。可能會出現這樣的情況:只有ptrobjF1的內存需要創建(或)可能出現需要創建內存的所有三個成員的座標。

由於所有三個指針都是公共的,所以它將被正在使用該類的最終用戶訪問。

說假設我正在爲類中的數據成員之一(ptrobjF1)創建內存,並將其他兩個數據成員留作NULL。在這種情況怪異如果任何體訪問中的數據成員的類之外的如下文

A obja; 
(obja.ptrobjF3)->Some_function(); // Program crahses because dereferncing NULL 

是否有任何設計圖案,以避免訪問哪個是左unintialized數據成員?

+3

是的,有一種模式:'如果(obja.ptrobjF3)(obja.ptrobjF3) - > Some_function();'如果你不想阻止訪問未初始化的指針,使它們私有,並提供適當的getter函數。 –

+0

如果函數沒有初始化,應該是什麼默認行爲?應該使用它能夠調用它嗎?否則,用戶應該檢查0。 –

+0

@πάντα-ῥεῖ如果我在很多地方使用該指針成員,那麼每次都難以檢查nullness –

回答

1

你最好把指針指向私有成員,然後通過getter函數控制它們的分配。這方面的一個概要:

class A 
{ 
public: 
    ClassF1& getF1() 
    { 
     if (!ptrobjF1) 
     { 
      ptrobjF1 = new ClassF1{}; 
     } 
     return *ptrobjF1; 
    } 

    A() : ptrobjF1{nullptr} {}  

    ~A() 
    { 
     delete ptrobjF1; 
    } 

private: 
    ClassF1 *ptrobjF1; 
}; 

當然,你還應當執行錯誤處理,當分配失敗,想想拷貝構造,你需要的常量,正確處理等

...或者你可以(也應該)迴避了一些問題,只需使用一個std::unique_ptr

class A 
{ 
public: 
    ClassF1& getF1() 
    { 
     if (!ptrobjF1) 
     { 
      ptrobjF1 = std::make_unique<ClassF1>(); 
     } 
     return *ptrobjF1; 
    } 

private: 
    std::unique_ptr<ClassF1> ptrobjF1; 
}; 
+0

在調用'delete'之前,您不需要爲'NULL'測試'ptrobjF1'。另外,您應該在'A'的構造函數中將'ptrobjF1'初始化爲'NULL'。 –

+0

getF1()返回什麼? –

+0

當然,都是如此。 – TartanLlama

1

您可以使用異常

class WrongAccess 
{}; 

class A 
{ 
private: 
    ClassF1 *ptrobjF1; 

public: 
    ClassF1* getF1() 
    { 
     if(ptrobjF1) 
     { 
      return ptrobjF1; 
     } 
     else 
     { 
      throw WrongAccess(); 
     } 
    } 

    A() 
    { 
     ptrobjF1 = NULL; 
    } 
}; 


A obja; 
//Do something 
... 
try{ 

    obja.getF1()->SomeFunc(); 
} 
catch(WrongAccess &e) 
{ 
    ///some handling 
    ... 
}