2014-10-26 59 views
0

我有這種情況在我的手裏:如何執行另一個對象實例化對象(依賴於它)在C++

  1. 對象A依賴於一個或多個對象B(及其後代)。
  2. 對象A和B可以有多個實例。哪個應該插入某處的列表中(擁有它們的對象A內的矢量形式的B對象列表)。
  3. 對象B(和其後代)不能住另一對象和對象A.一個唯一的對象特別
  4. 因此內部,對象B不能被對象A的外面實例化
  5. 如果對象A已經被實例化,它可以即時創建對象B(及其後代)的實例,並將其推入對象B的向量中。
  6. 對象A和對象B都可以無限導入許多變體。

到目前爲止,我已經提出了兩種解決方案,我不認爲它們都是錯誤的。

解決方案#1:

使用經理+工廠類這將創建和對中的兩個對象A和B. 這也將管理對象A的列表/矢量

這個問題是: 1.我需要將經理+工廠對象的實例傳遞給任何需要實例化對象A和B的對象。 2.因爲我無法確定有多少變種對象A和B的將來會派生出來,我不能做一個開關/事例實例化。或者如果我們採用工廠模式的方式,我必須強制對象A和B的每個孩子都應該有一對工廠類。有點乏味,如果你問我,可能會膨脹應用程序。 3.不能執行上述規則的第3和第4點。除了隱藏構造函數並將其設置爲private/protected,並將manager + factory類作爲好友類。

溶液#2:

製作對象A本身管理,並且將其存儲到參考在創建一個構件靜態 矢量。對象B只能通過名爲「AddB()」的方法 來創建,該方法將有一個模板類作爲輸入, 並且在該方法內部,它將實例化模板類並將其存儲到對象B的向量 中。

與這一個問題是:1。 我真的不能確保這是輸入模板類實際上是對象B的子/推導,因爲它是一個模板畢竟。 2.很可能會增加一些性能,因爲它畢竟是一個模板。僅供參考,我可能需要經常實例化它,即使在2000左右的時候也是如此。 3.它仍然不能執行上述規則的第3和第4點。除了隱藏構造函數並將其設置爲private/protected,並將A類作爲B類的一個好友類之外。

那麼,有關如何解決這個最佳方式的任何想法?

在此先感謝。

+0

是類「B到A的客戶端可見,或者只是一個? – MtRoad 2014-10-26 15:07:54

+0

B對於A的客戶也是可見的。只有在需要時,B和變量的每個變量都應該有一個getter方法。哦,我也忘了提及,對象A控制着B的生命週期。所以如果擁有它的A被刪除,B將被刪除。爲了更好地說明這一點,將A作爲具體對象,將B作爲A的特徵/組成部分。 – 2014-10-26 17:10:08

+0

誰在擴展A和B?是你,還是它需要你的代碼的其他用戶可擴展? – MtRoad 2014-10-26 17:51:28

回答

1

對我來說,它看起來像「因此,對象B不能在對象A之外實例化。」是問題的關鍵。

模板路徑可能是最好的,因爲如果類不是矢量類型的子類,它會生成編譯時錯誤。我還將每個B(動物)類都作爲A的朋友,所以A可以使用私有構造函數。它吃封裝,可能很難維護,但它的工作。

例子:

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

class Farm; 
class Animal { 
    protected: 
    Animal() {} 
    public: 
    virtual ~Animal() {} 
    void makeSound() { cout << this->sound() << endl; } 
    virtual string sound() const = 0; 
    friend class Farm; 
}; 

class Cat : Animal { 
    protected: 
    Cat() {} 
    public: 
    virtual ~Cat() {} 
    virtual string sound() const { return "meow"; } 
    friend class Farm; 
}; 


class Dog : Animal { 
    protected: 
    Dog() {} 
    public: 
    virtual ~Dog() {} 
    virtual string sound() const { return "bark"; } 
    friend class Farm; 
}; 

class Tractor { 
    protected: 
    Tractor() {} 
    virtual ~Tractor() {} 
    virtual string sound() const { return "rummm!"; } 
    friend class Farm; 
}; 


class Farm { 
    vector< Animal * > animals; 

public: 
    template< typename AnimalType > 
    void create() { 
     animals.push_back(new AnimalType); 
    } 

    void disturbAnimals() { 
     for(auto animal : animals) { 
      animal->makeSound(); 
     } 
    } 
}; 


int main(int argc_, char ** argv_) { 
    Farm farm; 
    farm.create<Cat>(); 
    farm.create<Dog>(); 

    // Generates compile-time error 
    //farm.create<Tractor>(); 
    farm.disturbAnimals(); 

    return 0; 
} 
+0

感謝您的回答。你是對的,最重要的一件事是強制實例化只在對象A中。而且我也認爲模板方式是更好的解決方案。但有沒有可能不使用模板?我仍然對使用模板有所保留。 – 2014-10-27 05:57:14

+0

@Bawenang Rukmoko Pardian Putra,模板爲編譯時在模板中使用的每種類型生成專用代碼。但是,由於這個原因,模板本身非常快。甚至有一個專門用於模板編程的C++領域。 – MtRoad 2014-10-27 11:20:54

+0

IC。如果有的話,我沒有經常使用模板。所以我不知道。謝謝。 – 2014-10-27 13:04:14