仮想メソッドと基本クラスからの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
を介してDerivedClass
sメソッドにアクセスできるようにしますが、ポインターとポインターはDerivedClass
sの配列ですか?
配列のタイプが間違っています。ポインタではなく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
など)を使用することをお勧めします。コードを手動で作成する代わりにこれらのツールを使用すると、非常に少ない実行コストで多くの問題を透過的に処理できます。
単純な配列の代わりに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()) );
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() );
ポインタ配列を定義します。ポインタタイプはBaseClassです。そして、派生クラスへのポインタを配列の要素に割り当てます。と同じように:
BaseClass* base [2];
base[0] = new FirstDerivedClass;
base[1] = new SecondDerivedClass;
これが答えでした(Rubbyから)
BaseClass* Base[2];
Base[0] = new FirstDerivedClass;
Base[1] = new SecondDerivedClass;