0

おそらく誰かにとっては簡単な質問ですが、以下の例で何が間違っているのでしょうか? 内部に他のクラスのインスタンス化を含むグローバルクラスを構築しようとしています...どこが間違っているかは、以下の例に要約されると思います。*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();
}
4

6 に答える 6

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

B * b;

コンストラクターでは、新しく割り当てられた のアドレスが割り当てられ、その後忘れられる新しいローカル変数を宣言しています!B

インスタンス フィールドbは、コンストラクター内の同じ名前のローカル変数によって隠されているため、決して割り当てられません。

あなたはおそらくそうするつもりです

A() {
    b = new B;
}
于 2012-10-28T22:42:32.617 に答える
1
A()
{
    B *b = new B;
}

する必要があります

A()
{
    b = new B;
}

あなたのバージョンでは、A コンストラクターに b という変数があります。この変数は、b とも呼ばれる A クラス メンバーを非表示にします (これは明らかに使用したかったものです)。

于 2012-10-28T22:42:04.673 に答える
1

cosntructorA::A()では、メンバーを初期化しませんA::bが、代わりにローカル変数を初期化します。やってみてください:

A() {
     b = new B;
}

またはそれ以上:

A():b(new B) {}

さらに良いことに、生のポインターをまったく使用しないでください。

于 2012-10-28T22:43:13.853 に答える
1
B *b = new B;

bクラス メンバーをシャドウするという名前のローカル変数を作成しますb。クラスメンバーを初期化する必要があり、初期化リストで行う必要があります。

A() : b(new B) {}

次のステップは、delete動的に割り当てたポインターを呼び出さないことによって引き起こされるメモリー リークを修正することですが、これは学習課題であるため、(まだ) それほど重要ではありません。

于 2012-10-28T22:43:32.043 に答える
1

かなりの数の人々が、あなたが目にしている問題を解決する 1 つの方法を指摘していますが、コードを実際に改善する方法についてのアドバイスを (とにかく私には) 与えているようには見えません。

あなたの定義はBと呼ばれるものquasi-classです。B簡単に言うと、何も失うことなく大幅に単純化できます。

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

あなたが行った他のすべて (get/set、デストラクタ) は、まったく何も達成していません。あなたのAクラスはほとんど達成できないだけでなく、さらに不十分です。A他の人は、のコンストラクターがローカル オブジェクトを定義し、Bそのオブジェクトをリークする問題をすでに指摘しています。どれも(とにかく、私はまだ見たことがあります)、それを修正しても、オブジェクトの作成の一部としてオブジェクトを作成しても、オブジェクトを破棄しないため、 の定義はオブジェクトAをリークすることを指摘していませんそれを含むオブジェクトが破棄されたとき。BBABA

あなたのクラスがオブジェクト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;
}
于 2012-10-28T23:23:30.427 に答える
0

振り返ってみると、int 変数 b に名前を付けるという問題を難読化していましたが (b 以外の名前にする必要がありました!!)。そうは言っても、皆さんは私を初期化リスト、デストラクタ、そして最終的には構成のトピックに向けて「指摘」しました。どうもありがとうC++ でクラス構成を実装するには?

于 2012-10-31T02:35:00.437 に答える