という基本クラスがあるとしましょう
Class Base {
public:
std::string array[];
};
文字列配列のサイズは、別のクラスが拡張するまで決定されません。そのための正しい構文は何ですか?
EG、後で派生クラスで
Derived::Derived() {
array[] = new array[40];
}
という基本クラスがあるとしましょう
Class Base {
public:
std::string array[];
};
文字列配列のサイズは、別のクラスが拡張するまで決定されません。そのための正しい構文は何ですか?
EG、後で派生クラスで
Derived::Derived() {
array[] = new array[40];
}
C スタイルの配列を使用する場合は、サイズを固定し、コンパイル時に把握する必要があります。その場合でも、std::array<>
代わりに、より安全でオーバーヘッドのないラッパーを使用できます。
コンパイル時にコンテナーのサイズがわからないstd::vector
場合は、 (またはstd::deque
場合によっては、メモリ割り当てに関する要件に基づいて) を使用し、生のポインターによる手動のメモリ管理を回避することをお勧めしnew[]
ますdelete[]
。
#include <string> // For std::string
#include <vector> // For std::vector
class Base {
public:
std::vector<std::string> myVector;
};
さらに、この設計では、 のコンストラクタ (およびデストラクタ) で専用の作業を行う必要はありませんDerived
。のデフォルト コンストラクターによって行われたDerived
のが配列の割り当てだけだった場合、デフォルト コンストラクターを明示的に定義することをまったく回避し、コンパイラーに暗黙的にコンストラクターを生成させることができます。デストラクタについても同じ話です。
また、標準コンテナ クラスの名前 ( などarray
) を変数の名前として使用しないことをお勧めします。myArray
(または、上記の例のように) のようなものmyVector
がより適切な選択肢です。
あなたはそうしない。C++ の配列は、コンパイル時の固定サイズです。好みに合わせてサイズを変更することはできません。
言語機能のみを使用してこれを行う悪い方法は、実際にメンバーを次のようにすることstd::string*
です。
std::string* array;
std::string
次に、最初の要素へのポインターを に割り当てて、 の配列を動的に割り当てarray
ます。
Derived::Derived() {
array = new std::string[40];
}
これを行う良い方法は、ライブラリ機能を使用することです。標準ライブラリには、使用できるコンテナ タイプが用意されています。試してみてくださいstd::vector<std::string>
:
std::vector<std::string> array;
次のように 40 個の文字列を含むように初期化できます。
Derived::Derived()
: array(40)
{ }
std::vector<std::string>
サイズを気にする必要がないように、a を使用してみてはいかがでしょうか。新しいものが挿入されると、コンテナーは自動的にサイズ変更されます。
通常、文字列のベクトルを使用する方が適切なソリューションです。
しかし、これはうまくいきます:
Class Base {
Public:
std::string *array;
};
Derived::Derived() {
array = new array[40];
}
私は追加します:
Class Base {
Public:
std::string *arr;
Base():arr(nullptr){}
Base(sizr_t s):arr(new std::string[s]){}
~Base(){delete []arr;}
};
Derived::Derived():Base(40) { }
また、コピー/移動コンストラクターと割り当てを記述する必要がある場合があります。派生したものはあまり知らなくてもいいです。次に比較します。
Class Base {
Public:
std::vector<std::string> arr;
Base(){}
Base(sizr_t s):arr(s){}
};
他のすべての特殊関数: デストラクタ、コピー/移動コンストラクタ、代入は、コンパイラによって生成されます。そして、Derived のコンストラクタはまだ: Derived::Derived():Base(40) { } また... arr を非公開にするか、少なくとも保護したい場合がありますか?
正しい構文は次のとおりです。
std::vector<std::string> array;
死に至るまでのヒープ割り当てと同様に、次のように静的にサイズを変更できます。
template <int N>
class Base
{
public:
std::string array[N];
};
class Derived : Base<40>
{ ... }
長所: シンプルで、実行時の (比較的遅い) メモリ割り当てと、面倒なクリーンアップ (スマート配列ポインターなど) を回避します。短所: Base の各インスタンス化は個別の型であるため、少し肥大化して相互運用性が低下する可能性があります。