1

ここに私の最初の投稿があります!私はこのサイトを参照用として、また一般的な問題の解決策を見つけるために、長年にわたって使用してきました。残念ながら、私が直面しているこの問題は、ここではまだ見つかっていません! それで、ここにあります。私はしばらくの間、プロジェクトに取り組んできました。私のプログラムには数千行のコードがあるため、ここではすべてを投稿しません。基本的に、親クラスをコードのどこかで既に初期化されているクラスに変更したいサブクラスがあります。これが可能かどうか、またはそれが適切なコード プラクティスであるかどうかはわかりません。しかし、私はあなたたちにそれを判断させます!これが私が直面している問題です:

#include <stdio.h>

class Base

    public:
        int data;
        Base(int);
};

class Child : public Base
{
    public:
    Child(void);
        void run(Base*);
};

Base::Base(int var)
{
    data=var;
}


void Child::run(Base* base)
{
      this = base //I know that you can create a reference to the parent class
                    //by casting this pointer to a Base pointer, but was wondering
                   //if you can do this the other way around. 
    printf("%d\n",Base::data);
}

int main()
{
Base* base1 = new Base(5);
Base* base2 = new Base(3);
    Child one();

one.run(base1);

    delete base1;
    delete base2;
    base1=0;
    base2=0;
    return 0;
}

したがって、これがコンパイルされると (コンパイルされない場合) 5 のような出力が得られ、run メソッドのパラメーターを base2 に変更すると、3 のような出力が得られるはずです。これは可能ですか? ありがとうございました!

4

3 に答える 3

1

やりたいことを正確に行うことはできませんが、似たようなことはできるかもしれません。親クラスに別のインスタンスのコピーであるインスタンスを作成できるコピーコンストラクターがある場合、そのコピー コンストラクターを使用して、子オブジェクトの構築中に親オブジェクトを作成できます。

class Child : public Base
{
    public:
    Child(const Base &b) : Base(b) { ...}

これで、別のオブジェクトのパーツと同じパーツを持つChildオブジェクトができました。BaseBase

于 2012-07-28T20:40:59.437 に答える
1

いいえ、そのようなことはできません。This読み取り専用ポインターです。この線

 this = base;

構文エラーが発生します。

C++ の基底クラスは静的です。実行時に変更することはできません。

ただし、クラス (ベースと子の両方) に仮想関数がない場合は、次のように動作します。

(Base&)*this = *base;

同時に、私はあなたがこれをするのを思いとどまらせます。推奨しない理由は、そのようなコードは変更に対して非常に脆弱になるためです。たとえば、いずれかのクラスに仮想メソッドが追加されると、VMT が上書きされます。これは、多重継承では機能しない場合があります。MSVC を使った実験で、クラスのバイナリ レイアウトで基本クラスの順序が変更される場合があることに気付きました。

つまり、これは、コンパイラが使用するレイアウトが確実にわかっている場合に使用できます。コンパイラが将来このレイアウトを変更しないことが確実な場合。そうでない場合は、これを避けたほうがよいでしょう。

正しいアプローチは、特別なメソッドを作成し、フィールドごとにデータをコピーすることです。

于 2012-07-28T20:42:47.857 に答える
0

thisconst と考えてください。基本クラスへの参照を取得すると、サブクラスのサブセット (部分) への参照を取得するだけです。基本クラスのインスタンスは、クラス全体 (この場合はサブクラスのインスタンス) にしっかりとバインドされています。その基本クラスがどのように初期化されるかを指示することはできますが (Ernest の応答を参照)、そのリンクを解除することはできません。

通常、class-with-base-class のメモリ レイアウトは次のようになります。

[ ... | 基本クラス | ... ... ... ]

独立して存在するのではなく、文字通り埋め込まれています(次のことは正常ではありません。決して起こらないとまで言いますが、それは内部のコンパイラの選択です):

[ ... | 基本クラスへの参照 | ... ... .. ] [独立した基本クラスのインスタンス]

于 2012-07-28T20:44:56.533 に答える