【问题标题】:Dont allow use of default constructor in C++ [duplicate]不允许在 C++ 中使用默认构造函数 [重复]
【发布时间】:2018-05-15 23:57:46
【问题描述】:

我正在尝试在 C++ 中创建一个禁止使用默认构造函数的类。
尽管如此,我认为我失败了,或者我不了解幕后发生的事情。这是我目前所拥有的:

class Point {
public:
        float x;
        float y;
        Point(float newX, float newY); //Definition is irrelevant
        Point() = delete; //Default or "empty" constructor is forbidden, so deleted
}
/* ... */
int main(void)
{
        Point a(1, 2); //Ok, should be available
        Point b; //Ok, does not compile
        Point c(); //Not ok, it does compile :(
}

我的预期行为是不编译点 c。我会很感激帮助产生这种行为,或者如果不可能,解释为什么会这样。

提前谢谢你

【问题讨论】:

  • 我在之前的帖子中得到了答案:stackoverflow.com/questions/40683637/…。请注意,问题中发布的代码已更新以显示如何执行此操作。
  • c 不是对象。所以默认的 c'tor 不会被调用,别担心。

标签: c++ c++11


【解决方案1】:

正在发生的事情是一个令人烦恼的解析。您不是在声明一个对象,而是一个名为 c 且返回类型为 Point 的函数。


声明任何构造函数都会阻止编译器生成默认构造函数,所以用=delete声明是超流。


聚合初始化

如果你知道顺序,你甚至不需要构造函数:

Point p{newX, newY};

可以正常工作。


统一初始化语法

以后为避免此类情况,请使用{}

Point p{}; //default constructs

【讨论】:

  • 虽然您可能会认为=delete 是多余的,但也可以说它用作注释,明确表明程序员打算不创建该构造函数。
  • @TCD,我也期待评论为什么。在这种情况下,很明显默认 init 会导致未初始化的值出现问题。
  • 默认构造函数没有会导致问题。在这种情况下,隐式生成的可以。你可以写一个显式的Point() : x{0}, y{0}{} 作为默认构造函数。如果您只看到重载的构造函数,那么您可以假设程序员可能没有忘记编写默认构造函数。但是有可能他们没有考虑它,只是忘记添加它。但是,如果您看到它被明确删除,那么您就知道这是他的意图。
【解决方案2】:

线

    Point c(); //Not ok, it does compile :(

不被解释为创建一个 Point 类型的对象 c,它被解释为声明一个新函数 c,它返回一个 Point 并且不接受任何参数。看这里: https://en.wikipedia.org/wiki/Most_vexing_parse

这一行也不需要:

    Point() = delete; //Default or "empty" constructor is forbidden, so deleted

如果您声明任何构造函数,则默认构造函数将被覆盖。

【讨论】:

    【解决方案3】:

    它确实可以编译,但只是因为它不是你想的那样。您正确地删除了默认构造函数。实际上已经声明了一个非默认构造函数会阻止该类是默认可构造的:

    struct Foo {
        Foo(int);
    }
    
    Foo x; // wont compile
    

    将默认构造函数声明为已删除是一种很好的做法,因为它明确指出默认构造函数是故意遗漏的。

    为什么会编译?

    Foo x();
    

    声明一个返回Foo的函数。这被称为最令人头疼的解析。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 2013-11-06
      • 2015-10-04
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多