web-dev-qa-db-ja.com

基本クラスの配列へのポインタ、派生クラスを入力します

仮想メソッドと基本クラスからの2つの派生クラスのみを含む基本クラスがあり、それらの仮想メソッドが実装されている場合。

どうすればよいですか:

 // causes C2259
 BaseClass* base = new BaseClass[2];

 BaseClass[0] = new FirstDerivedClass;
 BaseClass[1] = new SecondDerivedClass;

または:

// causes "base is being used without being initialized"
BaseClass* base;
// causes CC59 again
BaseClass* base = new BaseClass;

base[0] = FirstDerivedClass();
base[1] = SecondDerivedClass();

(または同様のもの)

... BaseClassを介してDerivedClasssメソッドにアクセスできるようにしますが、ポインターとポインターはDerivedClasssの配列ですか?

12
Deukalion

配列のタイプが間違っています。ポインタではなくBaseClassオブジェクトインスタンスを格納します。 BaseClassは抽象的であるように思われるため、コンパイラは、配列を満たすためにインスタンスをデフォルトで構築できないと文句を言います。

BaseClassが抽象的でなかったとしても、配列を多形的に使用することはC++では big no-no なので、どのような場合でも別の方法で行う必要があります。

コードを次のように変更して、これを修正します。

BaseClass** base = new BaseClass*[2];

BaseClass[0] = new FirstDerivedClass;
BaseClass[1] = new SecondDerivedClass;

とはいえ、ほとんどの場合、プレーン配列の代わりにstd::vectorを使用し、ダムポインターの代わりにスマートポインター(std::shared_ptrなど)を使用することをお勧めします。コードを手動で作成する代わりにこれらのツールを使用すると、非常に少ない実行コストで多くの問題を透過的に処理できます。

10
Jon

単純な配列の代わりにstd::vectorを使用するのはC++です。

std::vector<BaseClass*> base;
base.Push_back(new FirstDerivedClass());
base.Push_back(new SecondDerivedClass());

Kerrek SBが気付いたように、最も安全な方法はstd::unique_ptrを使用することです。

std::vector<std::unique_ptr<BaseClass> > base;
base.Push_back( std_unique_ptr<BaseClass>(new FirstDerivedClass()) );
base.Push_back( std_unique_ptr<BaseClass>(new SecondDerivedClass()) );
3
Denis Ermolin

BaseClassに純粋仮想メソッドが含まれている場合、これはコンパイルに失敗します。

BaseClass* base = new BaseClass[2];

そうでない場合は、メモリリークが発生します。

C++では、これはstd :: vectorまたはstd :: arrayを使用して、ある種のスマートポインターを使用して実行されます。例えば ​​:

std::vector< std::shared_ptr< BaseClass > > arr( 2 );
arr[0].reset( new FirstDerivedClass() );
arr[1].reset( new SecondDerivedClass() );
2
BЈовић

ポインタ配列を定義します。ポインタタイプはBaseClassです。そして、派生クラスへのポインタを配列の要素に割り当てます。と同じように:

BaseClass* base [2];
base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;
0
user1203650

これが答えでした(Rubbyから)

BaseClass* Base[2];

Base[0] = new FirstDerivedClass;
Base[1] = new SecondDerivedClass;
0
Deukalion