【C/C++ explicit关键字】为什么有了explicit关键字的构造函数 就不能再有 其无参构造函数
在 C++ 中,如果你有一个带有 explicit
关键字的构造函数,你就不能有相同签名的无参构造函数(默认构造函数),除非后者也标记为 explicit
。这是因为无参构造函数可能会被用于隐式类型转换,而 explicit
关键字的目的就是防止这种隐式转换。
例如,考虑以下类定义:
class MyGraphicsItem : public QGraphicsItem {
public:explicit MyGraphicsItem(QGraphicsItem *parent = nullptr);// 以下默认构造函数的存在是有问题的,因为它与上面的构造函数重载MyGraphicsItem();
};
如果你尝试使用这个类,如下所示:
MyGraphicsItem item1; // 正确的调用,如果默认构造函数没有被声明
MyGraphicsItem item2(nullptr); // 正确的调用
item1
的创建将会失败,因为 MyGraphicsItem()
试图调用无参的默认构造函数,而这个默认构造函数与 explicit MyGraphicsItem(QGraphicsItem *parent = nullptr)
重载。由于存在一个带 explicit
的构造函数,编译器不允许隐式调用无参构造函数。
为了解决这个问题,你可以做以下几件事情之一:
-
删除无参构造函数,如果它不是必需的。这样,你只能通过显式地传递参数来创建
MyGraphicsItem
对象。 -
将无参构造函数也标记为
explicit
,这样它就不会被用于隐式转换:
class MyGraphicsItem : public QGraphicsItem {
public:explicit MyGraphicsItem(QGraphicsItem *parent = nullptr);// 将默认构造函数也标记为 explicitexplicit MyGraphicsItem() {// 构造函数实现}
};
- 提供一个不同的构造函数,如果你需要一个无参构造函数,你可以提供一个不同的构造函数,它不与带参数的构造函数重载:
class MyGraphicsItem : public QGraphicsItem {
public:explicit MyGraphicsItem(QGraphicsItem *parent = nullptr);// 一个不同的无参构造函数MyGraphicsItem() : MyGraphicsItem(nullptr) {// 构造函数实现}
};
在这个例子中,无参构造函数显式地调用了带 explicit
的构造函数,这样它就不会与带参数的构造函数重载。
总之,当你在类中使用 explicit
关键字时,你需要确保不会创建与 explicit
构造函数重载的无参构造函数,除非你也将其标记为 explicit
。这样可以避免编译器错误,并确保类型的安全使用。