2015-12-17 362 views
0

這是一個極端新手問題很可能,但這是我不明白的東西。這可能是愚蠢的簡單,但我沒有很多的C++經驗,我正在努力學習。C++類的成員與構造函數

我試圖用我想了解的簡化版本來解釋它。

我有一個叫做Foo的類。它的構造函數有兩個參數。

我有一個名爲Bob的類,我想要一個Foo的私有實例,但是,我不知道傳遞給foo構造函數的參數,直到我進入到Bob的構造函數中。

class Foo 
{ 
public: 
    Foo(int a, int b); 
    ~Foo(); 

    int getA(); 
    int getB(); 
}; 

class Bob 
{ 
public: 
    Bob(); 
    ~Bob(); 

    void DoSomethingHere(); 
private: 
    Foo foo; 
}; 

當我編譯代碼時出現錯誤。

error: no matching function for call to 'Foo::Foo()' 

基於此,我猜測它試圖自動調用foo的構造函數,但不知道如何。 在Bob類的代碼中,我想要做這樣的事情。 (bob.cpp)

Bob::Bob() { 

    // do stuff to calculate the values of a and b 

    int a = 12; int b = 23; 

    // Initialize foo with the calculated values 
} 

鑑於我不知道傳遞給它的參數,直到我在Bob的代碼中,我該如何處理?

+1

關鍵字:'成員初始化list' –

+1

'Foo'沒有默認的構造函數。使'foo'成爲一個指針/智能指針,它將在'Bob'中初始化。或者爲'Foo'提供默認的ctor,並添加類似'void Foo :: setA(...)','void Foo :: setB(...)'的方法,這個方法將在'Bob' ctor中調用。 –

+0

'Bob :: Bob():Foo(calc_a(),calc_b()){}' –

回答

1

C++標準C++ 11和C++ 14的最新版本中有各種各樣的特性,比如嵌套構造函數,可以在這裏使用。但是,還有幾種可供選擇的方法,您應該提供一個更詳細的示例來說明您要完成的任務。

我將提供一個使用嵌套構造函數的簡單答案。假設兩個參數Foo的構造必須來自外部函數,first_foo_parameter(),和second_foo_parameter():

extern int first_foo_parameter(), second_foo_parameter(); 

然後,默認的構造函數可以這樣工作:

class Bob 
{ 
public: 
    Bob() : Bob(first_foo_parameter(), second_foo_parameter()) {} 

    ~Bob(); 

    void DoSomethingHere(); 
private: 

    Bob(int a, int b) : foo(a, b) {} 

    Foo foo; 
}; 

如果私有類成員的構造函數參數將以更復雜的方式派生,還有其他不同的技術可以沿着相同的方向使用。有時候,答案是重構類層次結構,例如首先初始化的私有超類,其構造函數可以自由地進行所有需要的計算,然後在構造子類的成員時,所有構造函數的構造函數參數在完全構建的超類中很容易獲得。

答案真的取決於具體的細節。一般的方法是使用嵌套構造函數或私有超類來幫助確定所有成員構造函數的參數。

+0

值得一提的是,對於簡單的情況,使用lambda而不是'first_foo_parameter()'和'second_foo_parameter'會很遠更優雅,提高代碼的可讀性。例如用'[](int d)替換'first_foo_parameter()'{/ *在這裏做些什麼* /;返回d; }' – silvergasp

+0

優秀的答案然而+1 – silvergasp

-1

將以下內容作爲公共職能:

Foo::Foo() 

你可以有多個構造函數的類。如果沒有給出參數並且它看起來像編譯器正在尋找的那樣,這個被調用。

+0

不幸的是,這並沒有回答這個問題。 –

0

我認爲一個指針可能是你想要的。

class Foo 
{ 
public: 
    Foo(int a, int b) : a(a), b(b) {} 
    ~Foo() {} 

    int getA(); 
    int getB(); 
private: 
    int a; 
    int b; 
}; 

int Foo::getA() { 
    return a; 
} 

int Foo::getB() { 
    return b; 
} 

class Bob 
{ 
public: 
    Bob(); 
    ~Bob(); 

    void DoSomethingHere(); 
private: 
    Foo* foo; // <--- Here is a pointer to foo. 
}; 

Bob::Bob() { 

    // do stuff to calculate the values of a and b 

    int a = 12; int b = 23; 

    // Initialize foo with the calculated values 
    foo = new Foo(a, b); // <-------- Here we create a new Foo object. 
    std::cout << foo->getA(); // <--- Use `->` to reference method or field. 
} 

Bob::~Bob() { 
    delete foo; // <--- Deallocate the object. 
} 

在客戶端類,您可以創建一個默認的構造函數新Bob對象。

int main() 
{ 
    Bob bob; 
} 
0

使用某種指針的位置和計算你的價值觀之後創建Foo對象。 std :: unique_ptr在這裏適合。

class Foo 
{ 
public: 
    Foo(int a, int b); 
    ~Foo(); 

    int getA(); 
    int getB(); 
}; 

class Bob 
{ 
public: 
    Bob(); 
    ~Bob(); 

    void DoSomethingHere(); 
private: 
    std::unique_ptr<Foo> foo; // <---- Here 
}; 

並初始化這樣的:

Bob::Bob() { 

    // do stuff to calculate the values of a and b 

    int a = 12; int b = 23; 

    // Initialize foo with the calculated values 
    foo = std::make_unique<Foo>(a, b); // <---- And here 
}