デフォルトのコンストラクタを使用できなくすることは問題ありませんか?


14

デフォルトのコンストラクターについて具体的に尋ねる

コンストラクターがオブジェクトのすべてのデータを初期化する場合、適切な初期化なしでは使用できないクラスを作成すると、デフォルトのコンストラクターが役に立たなくなるわけではありませんか?考慮してください:

// A class for handling lines in a CSV file
class CSV_Entry {
private:
    unsigned num_entries;
    std::string string_version;
    std::vector<std::string> vector_version;
    ...etc
public:
    CSV_Entry();
    CSV_Entry(const std::string& src_line);

    // returns a vector copy of the original entry
    std::vector<std::string> get_vector_snapshot();
}

int main( void ) {
    ...etc

    CSV_Entry example = CSV_Entry();
    std::vector<std::string> current_entry = example.get_vector_snapshot();

    ...etc
}

その変数current_entryは本質的に無駄ではありませんか?誰かが後でそれを処理しようとすると、おそらくエラーになります。その後、そのようなエラーを処理するコードを作成します...

このような追加の不必要なコードを軽減するために、デフォルトのコンストラクターを使用不可にしないのはなぜですか?そのようです、

...etc

CSV_Entry() {
    throw Verbose_Exception( "CSV_Entry: do not use the default constructor" );
}

...etc

PS:サイドノートで、デフォルトのコンストラクタを使用できないようにするだけで良い場合、他の実装の詳細は明らかにされていないので、そのスローをヘッダーに入れても問題ありませんか?

回答:


34

はい、引数なしでオブジェクトを初期化する賢明な方法がない場合、デフォルトのコンストラクターを使用不可にすることは問題ありません(実際には良いことです)。ただし、例外をスローして「無効」にしないでください。代わりにプライベートにします。理想的には、インターフェイスに、人々が「想定されていない」呼び出しを行うメソッドやコンストラクターを含めないことが理想です。


1
だから、それをプライベートにすることで、デフォルトのコンストラクタを使用しようとしているユーザーはコンパイル時にエラーを取得しますか?
user2738698

@ user2738698正しい。
ドーバル14年

8
C ++ 11を使用できる場合は、明示的に削除済みとしてマークしますCSV_Entry() = delete;
bstamour

13
実際、これよりも簡単ではないですか?デフォルト以外のコンストラクタが定義されている場合、コンパイラは暗黙的にデフォルトのコンストラクタを作成しません。このクラスには、デフォルト以外のコンストラクターが定義されています(explicitBTWをお勧めします)。そのため、定義しないと存在しません。
フレッドラーソン14年

7
@FredLarson明示的に削除することは、それを削除する意図を表しているため、誰もそれが間違いだとは思わない。
ダークホッグ14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.