2014-09-02 162 views
6

我想注入一些基本的信息到它可以構建的派生類中。派生類不應該關心初始化這些信息,它應該在那裏。有沒有辦法從基礎實例創建派生實例?

通過繼承可以輕鬆實現。但問題是基類不知道它自己的值。相反,他們需要作爲參數傳入。但是,由於派生類不需要考慮這一點,因此通過派生構造函數對參數進行隧道傳輸,而該構造函數使用它構造基礎構造函數是沒有選擇的。

我能想到的唯一解決方案是使信息靜態可用,以便基類可以在沒有幫助的情況下得到它們。但我想避免這種情況。

是否有某種方式首先創建並初始化基類,然後將實例擴展爲派生類型?如果沒有,我怎樣才能使用C++的可用特性來實現創建和依賴的順序?

#include <string> 
#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base(string name, int age) : name(name), age(age) {} 
protected: 
    const string name; 
    int age = 0; 
}; 

class Derived : public Base { 
    Derived() { // No parameters here, no call to base constructor 
     cout << "My name is " << name << " and I'm " << age << "." << endl; 
    } 
} 

Base base("Peter", 42); 
Derived derived(base); // "My name is Peter and I'm 42." 
+1

你的「沒有調用基礎構造函數」讓我回答:不。這不是C++的工作原理。 – Quentin 2014-09-02 21:21:41

+1

TL; DR; [原型模式](http://sourcemaking.com/design_patterns/prototype)可能有助於您的使用案例。 – 2014-09-02 21:21:54

回答

6

「的信息應該只是在那裏」的聲音,我喜歡它允許兩種可能的解釋:

  • 的信息實際上是在全球範圍內恆定的,可以是硬編碼:

    Derived() : Base("Peter", 42) {} 
    
  • 你的意思是「底座應該在那裏」:

    Derived(const Base & b) : Base(b) {} 
    
+0

信息不能被硬編碼。但是,第二個選項看起來很有趣。那會使用'Base'的默認拷貝構造函數還是我必須自己實現? – danijar 2014-09-02 21:26:22

+0

它會使用默認的副本,除非你提供一個 – Pete 2014-09-02 21:29:04

+0

@danijar:它將使用任何一個「Base」的拷貝構造函數都是通過重載分辨率來選擇的...... – 2014-09-02 22:12:38

3

一種選擇是可用的組合物,這意味着Base將是Derived一個實例變量:

#include <string> 
#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base(string name, int age) : name(name), age(age) {} 
    const string name() { return name; } 
    int age() { return age; } 
protected: 
    const string name; 
    int age = 0; 
}; 

class Derived { 
    Derived(Base b): base(b) { // No parameters here 
     cout << "My name is " << base.name() << " and I'm " 
      << base.age() << "." << endl; 
    } 

private: 
    Base base;  
} 

Base base("Peter", 42); 
Derived derived(base); // "My name is Peter and I'm 42." 

注意如何Derived不再延長Base(也許是名字就需要改變) ,並且每個調用Base中的實例變量現在都是方法調用。

5

將原已分配的類型擴展爲派生類型是不可能的原因:如果派生類型添加了字段,您將如何確定預先正確的大小?

一種可能的方式是隻有構造函數接受Base實例或operator=

但是在這個例子中你可能想考慮使用組合繼承。如果Base僅用作Derived的模板,則它不是繼承關係的好例子。

+0

我認爲是構圖,但感覺不對。在我的應用程序中,它是關於定期更新的組件。組成意味着具體組件不再是組件,而是具有「jetpacks」的正常類。我當前的解決方案是提供一個額外的'void initialize()'方法,在構造成員之後被外部調用。但是,這些值在派生構造函數中不可用。 – danijar 2014-09-02 21:58:37

相關問題