在继承的情况下编译器创建默认构造函数和用户创建默认构造函数之间的区别

Posted

技术标签:

【中文标题】在继承的情况下编译器创建默认构造函数和用户创建默认构造函数之间的区别【英文标题】:Difference between compiler creating default constructor and user creating default constructor in case of inheritance 【发布时间】:2018-03-16 06:28:21 【问题描述】:

我想知道以下两个代码的确切区别。我很清楚,如果我正在创建 Derived 类的对象,那么这两个程序都会抛出错误。这是因为基类的构造函数是私有的。

我正在使用以下版本的 gcc gcc 版本 4.8.3 20140627 [gcc-4_8-branch 修订版 212064] (SUSE Linux)

请告诉我为什么第一个程序在编译时没有显示任何错误。但第二个显示编译错误。

No error
****************************************
class Base

    private:
    Base()     
    
         cout << "Base constructor" << endl;    
    
;
class Derived:public Base

;
int main()

    return 0;



Throwing Error at compilation time
*****************************************
class Base

    private:
    Base()
    
         cout << "Base constructor" << endl;
    
;
class Derived:public Base

    public:
    Derived()
    
    
;
int main()

     return 0;

【问题讨论】:

编译器生成的构造函数和用户定义的构造函数(甚至是空的)之间的一个区别是编译器生成的构造函数是trivial,而用户定义的构造函数从来不是。 【参考方案1】:

编译器为第一个Derived隐式声明的默认构造函数定义为删除;如果您尝试使用该构造函数,则会发生编译错误。在第二个Derived 中显式声明的构造函数试图调用私有基构造函数,因此定义本身是错误的。

【讨论】:

感谢您提供宝贵的 cmets....我想知道即使我们没有创建对象,Derived 也会尝试调用私有基础构造函数。第一个Derived定义为已删除是什么意思。 @user2390140 编译器有责任确保您的代码遵循 C++ 语言的规则。这些规则之一是在私有名称所属的类之外禁止访问私有名称。即使您没有在main 中创建Derived 对象,其他一些翻译单元也可能会。 @user2390140 “定义为已删除”表示该函数被定义为就好像它的定义是= delete;。任何尝试 odr 使用该函数都将导致编译错误。

以上是关于在继承的情况下编译器创建默认构造函数和用户创建默认构造函数之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

C# 继承和默认构造函数

8-4:C++继承之子类的默认构造函数如何使用

Compact Framework - 如何在没有默认构造函数的情况下动态创建类型?

为啥 C++ 构造函数在继承中需要默认参数?

在声明然后分配对象的情况下创建的临时对象

默认构造函数是不是初始化内置类型?