【问题标题】:At what condition is the default constructor generated?默认构造函数是在什么条件下生成的?
【发布时间】:2012-05-17 15:17:19
【问题描述】:

我有以下课程:

class Tileset { //base class

public:
    static std::vector<Tileset*> list;
    virtual ~Tileset() = 0;

protected:
    std::vector<Tile> tiles_list;
    sf::Texture sheet;

private: //non copiable
    Tileset(const Tileset&);
    Tileset& operator=(const Tileset&);
};

其中sf::Texture 有一个默认构造函数

据我了解,应该生成一个默认构造函数,因为每个成员也可以默认构造。 然而,当我尝试在不调用 Tileset 构造函数的情况下构造派生对象时出现编译器错误。 谁能解释一下为什么没有生成默认构造函数?

编辑:忘了提到Tile 类没有默认构造函数。我不确定这是否会改变任何事情

【问题讨论】:

标签: c++ constructor default-constructor


【解决方案1】:

如果满足以下任一条件,则不会生成默认构造函数

  • 声明了一个用户定义的构造函数
  • 该类型有一个const 或引用字段

您声明了一个构造函数,因此 C++ 不会提供默认生成的构造函数。在这种情况下,虽然Tileset 的所有字段都有有用的默认构造函数,所以在这里定义默认构造函数非常容易

Tileset() { }

【讨论】:

  • 所以问题出在我的 Tileset(const Tileset&); ?然而它不是故意实现的(编译器在链接之前不会知道),所以我认为它在 C++11 之前是无法解决的?
  • @lezebulon:您可以从声明为私有的类继承,而不是声明复制构造函数和复制赋值运算符私有。这还具有使您的班级成员无法访问它们的优点。
  • 我刚刚测试过:Tileset(const Tileset&) = delete;它不应该使用它吗?因为我没有那样声明任何构造函数
  • @lezebulon:Mike 的基类已经被 Boost 实现为boost::noncopyable
【解决方案2】:

当您不提供任何构造函数时,编译器才会为您的类生成默认构造函数。如果你提供了一个构造函数(甚至是copy-constructor),那么编译器不会生成默认的构造函数。

“提供”是指当您声明并“可选地”定义类中的构造函数时。

【讨论】:

    【解决方案3】:

    来自 C++ 规范,12.1.5

    如果没有user-declared 类 X 的构造函数,则隐式声明默认构造函数。 隐式声明默认构造函数是其类的inline public 成员。

    您的 Tileset 类声明了一个构造函数,因此 C++ 编译器没有为您声明一个隐式构造函数。这种行为的基本原理是,由于您提供了带参数的构造函数,因此您可能需要这些参数才能正确初始化类的实例。这里的假设是,如果除了非默认构造函数之外还需要默认构造函数,您只需声明它即可。

    【讨论】:

    • @lezebulon 哎呀,只有一个 :)
    猜你喜欢
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2018-03-05
    • 1970-01-01
    相关资源
    最近更新 更多