2014-07-08 125 views
0

我懷疑如何在超類上沒有默認構造函數的情況下進行對象初始化。在C++上初始化類對象

#include <iostream> 

class A 
{ 
protected: 
    A(std::string title, int xpos, int ypos); 
}; 

class B : A 
{ 
protected: 
    //Is that correct? 
    A* m_pA(std::string title, int xpos, int ypos); 
    //Why not just A* m_pA;? 
public: 
    B(std::string title, int xpos, int ypos); 
}; 

B::B(std::string title, int xpos, int ypos) : m_pA(title, xpos, ypos) 
{ 
    //does nothing yet.  
} 

正如你可以看到我試圖初始化A類型的m_pA對象B的構造函數中,VC是扔我:

"m_pA" is not a nonstatic data member or base class of class "B"

你可以看到的例子編譯和錯誤here

我想知道爲什麼和如何在沒有默認構造函數的情況下初始化類的成員對象,以及爲什麼我錯了。

在此先感謝!

+1

你真的是從A繼承,並且有一個指向A的成員指針?無論如何,受保護的聲明是一種方法。你仍然需要初始化基地 – sp2danny

+0

'A * m_pA(std :: string title,int xpos,int ypos);'是B類函數返回指向A的指針。 – drescherjm

+0

yea @ sp2danny你可能是對的,我的頭,只是很困惑。 D: 無論如何,如果我想要一個類型爲A的對象,我該如何初始化它?我只想打電話給B,A會被初始化,這就是目標,問題可能不清楚......而且drescherjm你是對的! –

回答

1

當您構建子類時,您需要顯式初始化基類。

B(std::string title, int xpos, int ypos) 
    : A(title, xpos, ypos) 
{} 

你或許應該也常引用傳遞的字符串,否則你正在做不必要的副本一堆。

+1

至少解決所有問題...... – Deduplicator

+0

@Aesthete像'const std :: string&title'這樣的東西? –

+0

@eRafaelNunes - 是的,這就是我的意思。還要記住默認情況下繼承是'private',所以如果這不是你真正想要的,那麼你必須像'class B:public A'一樣繼承。祝你好運! – Aesthete

0
class B : A 
{ 
protected: 
    A* p; 
    A a; 
public: 
    B(std::string title, int xpos, int ypos) 
     : A(title, xpos, ypos)   // init base 
     , p(new A(title, xpos, ypos)) // init pointer 
     , a(title, xpos, ypos)   // init member 
    {} 
}; 
+0

特別是,構造函數在調用基類構造函數之前初始化數據成員。更廣泛地說,OP的問題是,他認爲他必須爲基類提供一個數據成員,當它真的隱含在派生類中。 – NicholasM

+0

@NicholasM:不。每個標準的構建順序:虛擬基礎,其他基礎,成員,按其定義的閱讀順序,而不是init列表。 – Deduplicator

+0

它旨在顯示所有他可能需要的東西的用例 – sp2danny

1

您的代碼有幾個錯誤。首先,對於繼承類來訪問受保護的變量/函數,繼承類必須有好友。其次,你的私有變量m_pA是一個指針。你不能一個指針初始化爲你A.實例看看這個代碼的方式:

#include <iostream> 

class A 
{ 
    friend class B; 
protected: 
    A(); 
    A(std::string title, int xpos, int ypos); 
}; 

A::A() 
{ 
//Do something 
} 
A::A(std::string title, int xpos, int ypos) 
{ 
//Do something 
} 

class B : A 
{ 
protected: 
    A* m_pA;  
public: 
    B(std::string title, int xpos, int ypos); 
}; 

B::B(std::string title, int xpos, int ypos) 
{ 
    m_pA = new A(title, xpos, ypos); 
} 

int main() { 

    return 0; 
} 

您可以驗證此:http://ideone.com/gL1OxH

+0

您的回答爲我提供了靈活的m_pA初始化,這就是我所需要的,我試圖完成您所做的一切,但沒有朋友班級B,我不知道關於:'對於一個繼承類來訪問受保護的變量/函數,繼承類必須被關聯'。 –

+0

很高興我代碼幫助。您也可以嘗試刪除「朋友類B」,並將B的類聲明更改爲:'class B:protected A',永遠不止一種方式來爲貓蒙皮。 – tpdietz