【问题标题】:Prevent implicit conversion of QObject* to bool : prevent 'Multiple constructor' warning防止 QObject* 隐式转换为 bool:防止“多个构造函数”警告
【发布时间】:2015-10-12 10:35:02
【问题描述】:

我遇到了与问题How to prevent implicit conversion from char array to bool相同的问题

我有一个这样的构造函数:

public:
Foo(Goo a=0, bool b=true, QObject* parent = 0);

我想阻止来电

Foo(aGoo, aParent);

其中aParent 隐式转换为bool。 (或与此相关的任何其他指针)

我通过定义实现了这一点

private:
Foo(Goo a, QObject* parent) {}

这会引发“多个构造函数”警告,我认为这是无害的,因为编译器将能够消除歧义。尽管如此,我想摆脱警告。是否有任何无警告的方法来防止隐式转换或抑制该警告?

编辑: 欢迎使用 C++11 解决方案。

【问题讨论】:

  • 我认为在这种情况下最明显的做法是避免使用默认参数值,因为它们具有误导性。开发人员实际上可能会编写Foo(aGoo, aParent),目的是将static_cast<bool>(aParent) 作为参数b 传递。当这些事情可能发生时,我认为最好实际强迫调用者思考他在做什么。
  • @GiulioFranco 在这种情况下有人使用QObject 作为bool 会很奇怪。如果他们真的想将QObject 用作bool,我很乐意强迫他们使用static_castb 实际上是 withTimer。尽管如此,您的观点是有效的,也许默认构造函数具有太多意义,无法保留它们。

标签: c++


【解决方案1】:

我假设该私有构造函数的规范与您描述的不同,因为它根本无法编译(第一个参数的默认值,但不是第二个参数)。

无论如何,显而易见的解决方案是不使用默认值,并提供一组表单的构造函数。

 public:

     Foo();
     Foo(Goo);
     Foo(Goo, bool);
     Foo(Goo, bool, QObject *);

 private:

     Foo(Goo, QObject*);   // leave this undefined.

这将为尝试调用私有构造函数的任何非成员或非朋友触发编译错误。对于会员和朋友,结果将是链接器错误。

在 C++11 中,您可以使用委托构造函数来减少代码重复。在 C++11 之前,使用由构造函数调用的通用辅助函数。

以上内容不会阻止编译器接受类似

 Foo afoo(AGoo, (double *)0);

不过,因为几乎任何指针都可以隐式转换为bool。如果您想停止这种情况,请将私有构造函数转换为模板。

【讨论】:

  • 如果您使用默认构造函数,通过添加私有构造函数,编译器/链接器会抛出错误还是会选择公共的、隐式转换的构造函数?
  • 在大多数情况下,您不能通过允许构造函数参数的默认值来做到这一点。编译器将选择最佳候选者(例如,它可以调用而不进行隐式转换的构造函数)。如果有多个相同的最佳候选,则代码将被视为不明确而被拒绝。但是,如果只有一个候选者,那么编译器会检查所选构造函数的访问(private 等)。它不会优先匹配公共构造函数而不是私有构造函数。
  • 然后,您使用默认构造函数的解决方案也将按预期工作,即阻止调用,因为它是私有的最佳候选。但是由于默认公共方法和私有方法的歧义,没有参数的“Foo()”调用无法编译。
  • 您误用了“默认构造函数”这个术语——它与对某些参数具有默认值的构造函数有所不同(尽管所有参数都具有默认值的构造函数可以用作默认值)构造函数)。无论如何,参数的默认值允许在某些情况下匹配,而我建议的技术可以避免这种情况。您错过了重点:在这种情况下不要使用默认值。
猜你喜欢
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-11
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多