首页 > 解决方案 > 构造函数“=default”和C++中编译器生成的构造函数有什么区别?

问题描述

代码示例:

class Dog
{
private:
    int x;
public:
    Dog()=default;
};

比。这段代码:

class Dog
{
private:
    int x;
};

“=default”的构造函数(第一个代码)和编译器创建的构造函数(如第二个代码)有什么区别?

标签: c++constructordefault-constructor

解决方案


Dog() = default;是用户声明的构造函数(不要与用户定义的构造函数混淆)。它是一个默认的默认构造函数。通常,当类具有其他构造函数但您仍然希望编译器生成默认构造函数(或者更确切地说是“默认默认构造函数”。这是最好的 C++ 术语。注意两个“默认”如何稍微不同的意思)。

用户声明的构造函数可防止类成为聚合。来自cppreference,仅适用于 C++20:

聚合是以下类型之一:

  • 数组类型
  • 类类型(通常是结构或联合),具有
    • 没有私有或受保护的直接非静态数据成员
    • 没有用户声明或继承的构造函数
    • 没有虚拟、私有或受保护的基类
    • 没有虚拟成员函数

例如,考虑:

#include <iostream>
#include <type_traits>

class Dog {
    int x;
public:
    Dog()=default;
};

class Horse {
    int x;
};

class Swan {
public: 
    int x;
};

class Cow {
public:
    int x;
    Cow() = default;
};

int main() {
    std::cout << std::is_aggregate_v<Dog>;
    std::cout << std::is_aggregate_v<Horse>;
    std::cout << std::is_aggregate_v<Swan>;
    std::cout << std::is_aggregate_v<Cow>;
}

输出

0010

前两个DogHorse类似于您的两个版本的Dog. 它们不是聚合,因为它们有私有成员。Swan是一个聚合,但Cow不是,因为它有一个用户声明的构造函数。

适用于聚合但不适用于非聚合的东西被指定为初始化器(相同的 cppreference 页面):

Swan s{.x=3};    // OK
Cow c{.x=4};     // Error: Cow is not an aggregate

TL;DR:我不知道你的两个Dogs 之间的区别,但一般来说,用户声明的构造函数的存在会有所不同。


推荐阅读