首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++默认构造函数语法

C++默认构造函数语法
EN

Stack Overflow用户
提问于 2014-05-16 14:44:51
回答 3查看 2.4K关注 0票数 5

关于C++中的默认构造函数,我有一个问题。例如,在A类中,使用这个默认构造函数A(){};A() = default;有什么区别?他们之间的一般区别是什么?

提前谢谢你!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-05-16 14:52:11

在第一个声明中定义为默认的构造函数被认为不是用户提供的。这在本质上类似于在C++03中隐含的内容。在聚合类中允许这样的构造函数声明。

代码语言:javascript
复制
struct ag {
    ag() = default;

    int a;
    double b;
};

struct nag {
    nag() {}

    int a;
    double b;
};

ag a = { 5, 12. }; // OK
nag na = { 5, 12. }; // error: not an aggregate and no appropriate constructor

此规则仅当= default出现在类中时才适用。鉴于这个类的定义:

代码语言:javascript
复制
struct nag {
    nag();

    int a;
    double b;
}; 

那么,这些构造函数定义实际上是完全等价的:

代码语言:javascript
复制
nag::nag() {} // 1
nag::nag() = default; // 2

explicit默认构造函数通常禁用空复制列表初始化语法(= {}),并禁用{}作为参数或return值。聚合中显式默认和explicit默认构造函数不受此规则限制,因为聚合初始化比构造函数初始化具有更高的优先级。这提供了一种检测类是否是聚合类的方法,但您可能不应该这样做。

代码语言:javascript
复制
struct sadistic {
    explicit sadistic() = default;

    // members
};

sadistic se = {}; // OK only if sadistic has no virtual functions, etc.
票数 6
EN

Stack Overflow用户

发布于 2014-05-16 14:56:57

对于A() {}A() = default;,每12.1p6默认构造函数的行为相同:

隐式定义的默认构造函数执行类的初始化集合,该类的初始化将由用户编写的该类的默认构造函数执行,没有ctor-初始化器(12.6.2)和空的复合语句。

不同之处是:

  • 构造函数是否为constexpr (显式默认构造函数为constexpr,如果这是有效的),
  • 类是否为聚合类(8.5.1p1),以及
  • 如果显式默认的默认构造函数是微不足道的(8.5p7),则值初始化是否会导致调用默认构造函数。

关于最后一点:

代码语言:javascript
复制
#include <iostream>

struct A { int i; A() = default; };
struct B { int j; B() {} };

int main() {
    int i = 42, j = 42;
    new (&i) A();
    new (&j) B();
    std::cout << i << std::endl;  // 0
    std::cout << j << std::endl;  // 42
}

因此,您可能希望编写一个用户提供的非默认的默认构造函数,例如,如果您的类有一些琐碎的成员,要实现零初始化(例如,一个大数组)将花费很大的代价,但这是一个非常特殊的情况。

票数 1
EN

Stack Overflow用户

发布于 2014-05-16 14:48:34

并没有太大的差别:

旧语法(注意不需要; ):

代码语言:javascript
复制
A() {}

从C++的第一天就可以使用了。它将默认构造每个基类和成员变量。

新的C++11语法:

代码语言:javascript
复制
A() = default;

这样做完全一样,但这是明确的默认,所以您(或编译器)不需要检查大括号是否真的是空的。

注意,如果类没有声明的构造函数,编译器将为您添加一个构造函数。

更正:如果删除默认构造函数,则存在差异,即类隐式默认构造函数无效。在本例中,{}是语法错误,而=default类似于已删除的定义:

代码语言:javascript
复制
struct S
{
    int &r;  //non default constructible

    S() {} //error: uninitialized reference S::r;
    S() = default; //ok: deleted constructor
    S() = delete;  //also ok (but not both!)
};
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23698203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档