使默认构造函数不可用就可以了吗?


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:顺便说一句,如果可以使默认构造函数不可用是很好的做法,那么将抛出的结果放在标头中就可以了,因为无论如何都不会公开其他实现细节?

Answers:


34

是的,如果没有明智的方法来初始化没有任何参数的对象,则可以使默认构造函数不可用(实际上是很好的)。但是不要通过抛出异常来“禁用”它。改为私有。理想情况下,您的接口将不包含人们“不应”调用的任何方法或构造函数。


1
因此,通过将其设为私有,试图使用默认构造函数的用户会在编译时收到错误消息吗?
user2738698 2014年

@ user2738698正确。
2014年

8
如果可以使用C ++ 11,则将其明确标记为Deleted :CSV_Entry() = delete;
bstamour 2014年

13
其实,难道不是比这容易吗?如果定义了任何非默认构造函数,则编译器将不会隐式创建默认构造函数。此类定义了一个非默认的构造函数(我建议使用explicitBTW)。因此,如果您不定义它,那么它将不存在。
Fred Larson 2014年

7
@FredLarson明确删除它表示删除它的意图,因此没有人认为这是一个错误。
Darkhogg 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.