默认构造函数(default constructor)常被用于对象的默认初始化或值初始化。
我的问题是:
如果类没有有意义的初始值,仍需要为类提供默认构造函数吗(不会违反类的不变式 class invariant)?
如果不提供默认构造函数,有什么坏的影响?
例如,一个人必须有名字,空字符串并不是一个有意义的名字。
提供默认构造函数:
#include <string>
class Person {
public:
Person() : name("") {} // 会导致类的对象存在无效状态
explicit Person(const std::string &n) : name(n) {}
private:
std::string name;
};
不提供默认构造函数:
#include <string>
class Person {
public:
explicit Person(const std::string &n) : name(n) {}
private:
std::string name;
};
补充
非常感谢回答问题的各位,但是感觉没有人回答到点上。这个问题是一个关于类的设计的问题,而不是技术上的问题。
怪我咯2017-04-17 13:27:04
类的构造函数会自动调用成员的默认构造函数, 如果你可以接受这种行为, 就可以不用特别的去手动调用.
比如你的代码里面, 不写name("")
其实就等于name()
.
我一般只给没有默认构造函数的成员初始化, 其他的都不会初始化, 比较特别的除外.
大家讲道理2017-04-17 13:27:04
一般都要提供默认构造函数,如果你要这样使用你的类的话:
Person persons[100];
std::list<Person> persons(100);
// 这里两行都会报错,因为没有默认构造函数。。。
// 以及很多STL容器、算法都要求,被使用类有默认构造函数
这个只是其中一方面,抛砖引玉一下,看看《effective C++》、《more effective C++》吧!这两本书将的比较透彻。
ringa_lee2017-04-17 13:27:04
你的问题不在于是否提供默认构造函数,你自己提供的和系统的默认构造函数没实质差别。
你纠结的是,无参构造函数实际上生成了一个初始状态无效的对象。
1、很多时候,这种临时的无效状态没啥影响,需要调用其它函数初始化就是。
2、你也可以定义一个默认构造函数,但是声明为private,世界就清净了。
我个人建议方案1,以为很多很多的原因,会导致一个对象很可能状态是不对的(比如对象持有一个网络连接,或者对象需要做账号密码授权操作,你没法把所有的工作都放在构造函数里面去)。只需要相关对应操作的时候对状态进行判断即可。