2

私は継承を使用するプログラムを作成しました。すべて問題ありませんが、自然にここにあるべきではないと思うエラーがあります。これが私のプログラムです:

class A
{
protected:
    int x;
public:
    A(){};
    ~A(){};
    A* operator=(const A* other)
    {
        this->x = other->x;
        return this;
    }
};
class B : public A
{
public:
    B() : A(){};
    ~B(){};
};
class C
{
protected:
    A *a;
public:
    C(const A* other){ *(this->a) = other; };
};

int main()
{
    B *b = new B();
    C *c = new C(b);
    return 0;
}

ステートメント'this->x =other->x;'で実行時エラーが発生します。これはどうですか?

4

2 に答える 2

7

*(this->a)は初期化されていないため、未定義this->aの動作です。これは単なるダングリングポインタです。

使用できますa = new A; *a = otherthis->この場合は冗長です)が、これは適切なC ++の方法ではありません-RAIIを使用する必要があります(調べてください)-必要な場合は、デストラクタ、代入演算子、またはコピーコンストラクタは必要ありません。

また、operator =通常は*this参照によって返されます。

于 2012-12-28T22:47:13.013 に答える
2

私はLuchianの答えが好きですが、コードに拡張する場所がまだいくつかあります。他の潜在的なバグを修正する前に、コードで未定義の動作が発生する可能性があります。

class A
{
protected:
    int x;
public:
    A():x(0){}     // should always initialize x in constructor
    virtual ~A()=0 {} // as A is a base case, ~A must be virtual
    A& operator=(const A& other)  // a reference will be more practical better?
    {
        this->x = other.x;
        return *this;
    }
};

Bを基本クラスとして提供することを意味する、Bオブジェクトも作成したくない場合は、デストラクタも仮想にし、純粋な仮想にする必要があります。

class B : public A
{
public:
    B() : A(){}
    virtual ~B(){} =0
    { }       
};

*(this->a) = other;すでにルチアンが答えています。member initialize list コードで、Aを指すポインターのコピーを保持する場合は、以下のデモコードを参照してa_ptrを初期化するだけです。

class C
{
protected:
   A *a_ptr;
public:
    C(A* other):a_ptr(other){ }
};

最後にメイン関数に行きます。b、cがメイン関数でのみ使用されている場合、プログラムが終了すると、システムは動的に割り当てられたメモリを要求a,bしますが、ループで使用する場合は、手動で削除する必要があります。

于 2012-12-28T23:15:43.327 に答える