4

プログラミングの割り当てをしている間、私は基本的なC++の概念に出くわしているようです。プログラムにバグが見つかりました。これは、デストラクタが予想よりも多く実行されたことが原因でした。これは、私が間違っていることを示すコードサンプルです。

#include <iostream>
using namespace std;

class A
{
public:
    A(int num)
    {
        number = num;
        cout << "A constructed with number " << number << ".\n";
    }
    ~A()
    {
        cout << "A destructed with number " << number << ".\n";
    }
private:
    int number;
};

class B
{
public:
    B(A pa)
        : a(pa)
    {
        cout << "B constructor run.\n";
    }
    ~B()
    {
        cout << "B destructor run.\n";
    }
private:
    A a;
};


int main()
{
    A foo(7);
    {
        B bar(foo);
    }
    //Pause the program.
    system("pause");
}

私が期待してA foo(7);いるのは、スタック上のスペースをAという名前のオブジェクトに割り当てfoo、コンストラクターを呼び出して、を渡すこと7です。コンストラクターが実行されたことを示す出力を割り当て7number出力します。ここで、名前の付いたオブジェクトB bar(foo);にスタック上のスペースを割り当て、コンストラクターを呼び出して、値を渡します。これは、の単なるコンテナーです。コンストラクターは、渡されたパラメーターを自身のプライベートデータメンバーに割り当て、出力を画面に出力します。BbarfoointAa

さて、bar閉じ中括弧でスコープから外れると、barのデストラクタが呼び出されることを期待します。これにより、出力が画面に出力され、データメンバーのデストラクタが呼び出されますA a。そのデストラクタは出力を画面に出力し、int number含まれていたものを破棄します。

私が期待する出力は次のとおりです。

A constructed with number 7.
B constructor run.
B destructor run.
A destructed with number 7.
//Destructors should be called in the reverse order of their construction right?

実際の出力:

A constructed with number 7.
B constructor run.
A destructed with number 7. //This is unexpected.
B destructor run.
A destructed with number 7.

その余分な破壊を引き起こしているのは何ですか?

4

4 に答える 4

3

コンストラクBターはAオブジェクトを値で受け取ります。つまりfoo、パラメーターpaにコピーされ、メンバーにコピーされますa。コンパイラーはコピーの1つ(コンストラクターへの引数)を削除できましたが、もう1つは削除できず、2番目Aのオブジェクトが破棄されます。

于 2012-06-04T01:31:07.157 に答える
2

明らかに、メンバー データ A a から取得されます。クラスBの.クラスAのデフォルトのコピーctorで構築されているため、Aからのコンストラクト出力が表示されない理由は疑問だと思います。クラスAのコピー-ctorを1つ追加して、コンストラクトが表示されるようにすることをお勧めします手順。

A(const A& a)
{
     number = a.number;
     cout << "A copy-constructed with number " << number << ".\n";
}
于 2012-06-04T01:51:25.170 に答える
1

「foo」や「bar」でかわいくなると嫌いです。

しかし、「A」の2つのインスタンスが構築されているのがわかります。1つは明示的に、もう1つは「B」によって暗黙的に作成されています。そして、2つのデストラクタが呼び出されます。

この写真の何が気に入らないのですか;)?

于 2012-06-04T01:30:29.737 に答える
0

クラスBには、 A a Bオブジェクトを破棄するためのメンバーが1つあるため、最初にそのメンバーのデストラクタを呼び出します。

于 2012-06-04T01:30:00.627 に答える