Apakah boleh membuat konstruktor default tidak dapat digunakan?

14

Secara khusus bertanya tentang konstruktor default

Mengingat konstruktor menginisialisasi semua data untuk objek, jika saya membuat kelas yang tidak dapat digunakan tanpa inisialisasi yang benar, bukankah konstruktor default tidak berguna? Mempertimbangkan:

// 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
}

Variabel current_entryitu pada dasarnya tidak berguna, kan? Jika seseorang mencoba memprosesnya nanti, mereka kemungkinan akan mendapatkan kesalahan; maka mereka akan membuat kode untuk menangani kesalahan seperti itu ...

Untuk mengurangi kode tambahan yang tidak perlu seperti itu: mengapa tidak membuat konstruktor default tidak dapat digunakan? Seperti itu,

...etc

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

...etc

PS: sebagai catatan, jika boleh saja membuat konstruktor default tidak dapat digunakan, apakah boleh memasukkan lemparan ke header, karena tidak ada detail implementasi lainnya yang terungkap?

pengguna2738698
sumber

Jawaban:

34

Ya, tidak apa-apa (sebenarnya, itu baik ) untuk membuat konstruktor default tidak dapat digunakan jika tidak ada cara yang masuk akal untuk menginisialisasi objek tanpa argumen. Tapi jangan "nonaktifkan" dengan melemparkan pengecualian. Jadikan pribadi sebagai gantinya. Idealnya antarmuka Anda tidak akan berisi metode atau konstruktor apa pun yang orang "tidak seharusnya" panggil.

Doval
sumber
1
Jadi, dengan menjadikannya pribadi, pengguna yang mencoba menggunakan konstruktor default akan mendapatkan kesalahan pada waktu kompilasi?
user2738698
@ user2738698 Benar.
Doval
8
Jika Anda dapat menggunakan C ++ 11, maka secara eksplisit menandainya sebagai dihapus: CSV_Entry() = delete;.
bstamour
13
Sebenarnya, bukankah ini lebih mudah dari ini? Jika ada konstruktor non-default didefinisikan, kompiler tidak akan secara implisit membuat konstruktor default. Kelas ini memiliki konstruktor non-default yang ditentukan (yang saya sarankan adalah explicit, BTW). Jadi jika Anda tidak mendefinisikannya, itu tidak akan ada.
Fred Larson
7
@FredLarson Menghapusnya secara eksplisit menyatakan niat untuk menghapusnya sehingga tidak ada yang berpikir itu adalah kesalahan.
Darkhogg