2012-10-28 183 views
0

對於那裏的某個人來說可能是一個簡單的問題,但是我在下面的例子中做了什麼錯誤?我正在嘗試構建一個全局類,其中包含其他類的實例化...我認爲我出錯的地方歸結爲下面的示例。獲取seg錯誤,就好像* b從未創建過一樣。提前致謝!!如何初始化成員變量

#include <iostream> 

using namespace std; 

class A; 
class B; 

class B 
{ 
    public: 
    B() 
    { 
     b = 99; 
    } 
    ~B(); 

    int Getb() {return b; } 
    void Setb (int x) { b = x; } 

    private: 
    int b; 

}; 

class A 
{ 
    public: 
    A() 
    { 
     B *b = new B; 
    } 
    ~A(); 

    B * b; 

    void Printout() 
    { 
     cout<<b->Getb()<<endl; 
    } 
    private: 

}; 

int main() 
{ 
A *a = new A; 
a->Printout(); 
cin.get(); 
} 
+0

你聲明瞭析構函數,但從來沒有定義它們?或者是縮短的遺骸? – ypnos

回答

1
A() 
{ 
    B *b = new B; 
} 

應該

A() 
{ 
    b = new B; 
} 

在您的版本有一個在構造函數稱爲B變量。這個變量隱藏了A類成員,也稱爲b(這顯然是你想使用的)。

3
A() { 
    B *b = new B; 
} 

B * b; 

在你構造函數聲明一個新的局部變量是被分配的新分配B的地址,然後忘記了!

實例字段b永遠不會分配給它,因爲它在構造函數中被同名的局部變量遮蔽。

你大概的意思做

A() { 
    b = new B; 
} 
+1

我至少會提到使用初始化列表,而不是在構造函數體中初始化成員變量。 –

1

在cosntructor A::A()你不用來初始化的A::b成員,但局部變量來代替。嘗試這樣做:

A() { 
    b = new B; 
} 

或更好:

A():b(new B) {} 

更妙的是,不要使用原始指針都沒有。

1
B *b = new B; 

創建名爲b的局部變量,其陰影類成員b。您需要初始化類成員,並且您應該在初始化列表中執行此操作。

A() : b(new B) {} 

你的下一個步驟是確定引起從來沒有叫你動態分配的指針delete內存泄漏,但由於這是一個學習鍛鍊它可能不是非常重要的()。

1

儘管不少人已經指出瞭解決問題的方法之一,但無論如何,(無論如何)似乎都沒有提供關於如何更好地實現代碼的建議。

您的B的定義是所謂的quasi-class。爲了使長話短說,你B可以簡化很多沒有失去任何東西:

struct B { 
    int b; 
    B() : b(99) {} 
}; 

一切你所做的(獲得/套,析構函數)是實現絕對沒有。你的A課程不僅能完成儘可能少的任務,而且還會做得更差。其他人已經指出A的構造函數定義本地B對象,然後泄漏該對象的問題。無論如何,我還沒有看到任何指示,即使您修復該問題,您的A定義也會泄漏B對象,因爲即使它創建B對象作爲創建A對象的一部分,它仍然會不是銷燬B對象時,包含它的A對象被銷燬。

我看不出有什麼理由讓您的A類動態分配B對象(或者,當您接近它時,甚至存在)。我定義A更是這樣的:

class A { 
    B b; 
public: 
    void print() { std::cout << b.b << "\n"; 
}; 

,這將是更好的,但是如果一個B對象知道如何將自身插入到數據流 - 如果它使用的是正常的語法,以及:

std::ostream &operator<<(std::ostream &os, B const &b) { 
    return os << b.b; 
} 

有了這個地方,你A類增加什麼都沒有,所以你的整個程序變得像這樣:

struct B { 
    int b; 
    B() : b(99) {} 
}; 

std::ostream &operator<<(std::ostream &os, B const &b) { 
    return os << b.b; 
} 

int main() { 
    std::cout << B() << "\n"; 
    return 0; 
} 
+0

我想你的意思是......操作符<<(...,A const&a){return os << a.b; }'。 :) – Xeo

+0

@Xeo:不 - 所有'A'加入的都是'Printout',它不應該在一個單獨的類中,所以根本沒有理由擁有'class A'。 –

+0

Woops,我沒有看到你在最後的片段中有效地將'A'重命名爲'B'。 :) – Xeo

0

大傢伙的提示s,儘管現在回想起來,我用命名int變量b(應該是除b之外的任何東西)來混淆我的問題。也就是說,你們「指出」我的方向是初始化列表,析構函數,最後是構圖主題。非常感謝How to implement class composition in C++?