C++ 默认构造函数与隐式构造函数

C++ 默认构造函数与隐式构造函数,c++,constructor,default-constructor,C++,Constructor,Default Constructor,可能有人已经问过了,但谷歌搜索“default”、“defaulted”、“explicit”等并没有给出好的结果。但无论如何 我已经知道显式定义的默认构造函数(即没有参数)和显式定义的默认构造函数(即带有关键字default)之间存在一些差异,从这里可以看出: 但是显式定义的默认构造函数和隐式定义的构造函数(即,当用户根本不编写构造函数时)之间有什么区别 vs 想到的一件事是,当存在非默认构造函数时,用户还必须显式定义默认构造函数。但还有其他区别吗 编辑:我最感兴趣的是知道是否有什么好的理由来

可能有人已经问过了,但谷歌搜索“default”、“defaulted”、“explicit”等并没有给出好的结果。但无论如何

我已经知道显式定义的默认构造函数(即没有参数)和显式定义的默认构造函数(即带有关键字
default
)之间存在一些差异,从这里可以看出:

但是显式定义的默认构造函数和隐式定义的构造函数(即,当用户根本不编写构造函数时)之间有什么区别

vs

想到的一件事是,当存在非默认构造函数时,用户还必须显式定义默认构造函数。但还有其他区别吗


编辑:我最感兴趣的是知道是否有什么好的理由来编写
A()=default
而不是完全省略构造函数(当然,假设它是类中唯一显式定义的构造函数)。

默认值的目的是使隐式定义显式化。隐式定义的版本和显式默认版本之间的任何差异仅限于由于显式声明的存在而出现的一些其他可能性

  • 隐式声明/定义的构造函数始终是
    public
    ,而显式定义的默认构造函数的访问控制由您自己控制

  • 通过定义默认构造函数,可以使用属性对其进行注释。例如:

    $ cat a.cpp 
    class A
    {
    public:
        [[deprecated]] A() = default;
    };
    
    int main()
    {
        A a;
    }
    
    $ g++ -std=c++14 a.cpp
    a.cpp: In function ‘int main()’:
    a.cpp:9:7: warning: ‘constexpr A::A()’ is deprecated [-Wdeprecated-declarations]
         A a;
           ^
    a.cpp:4:20: note: declared here
         [[deprecated]] A() = default;
                        ^
    
  • 下面给出的C++编程语言StruouUp第四版的书中明确了它们是等价的。


    显式默认值

    由于可以抑制生成其他默认操作,因此必须有一种方法 恢复默认值。此外,有些人更喜欢在程序中看到完整的操作列表 文本,即使不需要完整的列表。例如,我们可以写:

    class gslice {
        valarray<size_t> size;
        valarray<size_t> stride;
        valarray<size_t> d1;
    public:
        gslice() = default;    //<< Explicit default constructor
        ~gslice() = default;
        gslice(const gslice&) = default;
        gslice(gslice&&) = default;
        gslice& operator=(const gslice&) = default;
        gslice& operator=(gslice&&) = default;
        // ...
    };
    
    gslice类{
    阵列大小;
    步幅;
    Vald1阵列;
    公众:
    
    gslice()=default;//这很全面。谷歌搜索“C++默认”“C++删除”“C++显式”给出了非常好的结果。你试过了吗?在进行研究时,你还应该使用三个以上的谷歌关键词。阅读、研究、理解。@LightnessRacesinOrbit是真的吗?这些只是例子,我没有完全用谷歌搜索,也没有只用谷歌搜索这三个关键词。谷歌搜索时,例如“C++默认值”总的来说,我没有找到关于这个问题的好结果。当然,这是一个区别。你知道其他的吗?从所有的区别中,我看到似乎两个构造函数的行为都是相同的,但有一些区别是因为当你显式地写它时,你可以对它做一些事情。C正确吗?@NPS正确。我把你的评论纳入了答案中。
    $ cat a.cpp 
    class A
    {
    public:
        [[deprecated]] A() = default;
    };
    
    int main()
    {
        A a;
    }
    
    $ g++ -std=c++14 a.cpp
    a.cpp: In function ‘int main()’:
    a.cpp:9:7: warning: ‘constexpr A::A()’ is deprecated [-Wdeprecated-declarations]
         A a;
           ^
    a.cpp:4:20: note: declared here
         [[deprecated]] A() = default;
                        ^
    
    class gslice {
        valarray<size_t> size;
        valarray<size_t> stride;
        valarray<size_t> d1;
    public:
        gslice() = default;    //<< Explicit default constructor
        ~gslice() = default;
        gslice(const gslice&) = default;
        gslice(gslice&&) = default;
        gslice& operator=(const gslice&) = default;
        gslice& operator=(gslice&&) = default;
        // ...
    };
    
    class gslice {
        valarray<size_t> siz e;
        valarray<size_t> stride;
        valarray<size_t> d1;
    public:
        // ...
    };