Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 继承的默认构造函数也是用户定义的吗?_C++_C++11_G++_Clang_Default Constructor - Fatal编程技术网

C++ 继承的默认构造函数也是用户定义的吗?

C++ 继承的默认构造函数也是用户定义的吗?,c++,c++11,g++,clang,default-constructor,C++,C++11,G++,Clang,Default Constructor,报告清楚地解释了这一点 如果类或结构没有用户定义的默认构造函数,C++ 不允许默认构造它的常量实例,如 这([dcl.init],第9页) 下面的代码为Base提供了这样一个用户定义的默认构造函数,但是g++和Clang不同意Derived的默认构造函数是否是用户定义的,即使Derived确实显式继承了所有Base构造函数(使用) 但它不能解决叮当声错误。叮当声是正确的 有关const实例的相关段落来自8.5p7: 如果程序调用 const合格类型T,T应为用户提供的类类型 默认构造函数 由于B

报告清楚地解释了这一点

如果类或结构没有用户定义的默认构造函数,C++ 不允许默认构造它的常量实例,如 这([dcl.init],第9页)

下面的代码为
Base
提供了这样一个用户定义的默认构造函数,但是g++和Clang不同意
Derived
的默认构造函数是否是用户定义的,即使
Derived
确实显式继承了所有
Base
构造函数(使用

但它不能解决叮当声错误。

叮当声是正确的

有关const实例的相关段落来自8.5p7:

如果程序调用 const合格类型T,T应为用户提供的类类型 默认构造函数

由于
Base():b_0{}
是用户提供的,
Base const b很好

下一个重要部分是12.9p3:

对于继承的候选集合中的每个非模板构造函数 构造函数而不是没有参数的构造函数或 复制/移动构造函数如果只有一个参数,则 使用相同的构造函数特征隐式声明,除非 中有一个具有相同签名的用户声明构造函数 类中显示using声明的位置

这里的重要部分是粗体文本。我认为这排除了您的情况,因为
Base()
是一个没有参数的构造函数。这意味着
派生的
没有用户提供的默认构造函数(尽管仍然隐式声明了一个)


这也意味着基类中的默认、复制和移动构造函数是继承的。

你说得对,我误解了这个问题。+1谢谢你的回答。如果我将
Base
构造函数签名更改为
Base(int b=0,void*=nullptr):b_b(b){}
,则默认构造函数将被抑制。但是,Clang仍然在
派生的
上给出错误(并且g++接受它)。具有2个默认参数的构造函数是否也算作没有参数的非继承构造函数?@rhalbersma:是的,它仍然算作没有参数的非继承构造函数<代码>基(int)
基(int,void*)
是继承的。(但是,默认参数不是继承的)。如果我正确理解12.9p3部分,正确的解释(对于C++11)将是完全忽略
使用Base::Base
,因为唯一可以继承的构造函数没有参数,所以它不是。因此,即使没有const资格,它也不会起作用。奇怪的是,文本标准没有说明为什么默认结构在遗产中受到歧视。此外,该子句似乎已被删除,因为:继承构造函数并同时声明构造函数的类(因此没有隐式默认值)无法使用g++-4.8编译无参数声明,但可以使用g++-7.3
#include <iostream>

class Base
{
public:
    Base(): b_(0) {}  // look! user-defined default constructor
    void print() const { std::cout << b_ << "\n"; }
private:
    int b_;
};

class Derived
:
    public Base
{
    using Base::Base; // does this constitute a user-defined default constructor?
};

int main()
{
    Base const b;
    b.print();    // 0 for g++ & CLang

    Derived const d;
    d.print();    // 0 for g++, Clang: "default initialization of an object of const type 'const Derived' requires a user-provided default constructor"
}
Base(int b = 0, void* = nullptr): b_(b) {}