Чи добре робити конструктор за замовчуванням непридатним?


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
Отже, зробивши це приватним, користувач, який намагається використовувати конструктор за замовчуванням, отримає помилку під час компіляції?
користувач2738698

@ user2738698 Правильно.
Доваль

8
Якщо ви можете використовувати C ++ 11, а потім явно помітити його як видалити: CSV_Entry() = delete;.
bstamour

13
Насправді, хіба не простіше цього? Якщо визначені будь-які конструктори за замовчуванням, компілятор не буде неявно створити конструктор за замовчуванням. У цьому класі визначено конструктор за замовчуванням (який я рекомендую explicit, BTW). Отже, якщо ви просто не визначите це, воно не буде існувати.
Фред Ларсон

7
@FredLarson Явне видалення виражає намір видалити його, щоб ніхто не думав, що це було помилкою.
Darkhogg
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.