gpt4 book ai didi

c++ - C++默认构造函数

转载 作者:IT老高 更新时间:2023-10-28 21:51:01 26 4
gpt4 key购买 nike

给出以下代码:

class temp
{
public:
string str;
int num;
};

int main()
{
temp temp1;
temp temp2 = temp();

cout << temp1.str << endl; //Print ""
cout << temp2.str << endl; //Print ""

cout << temp1.num << endl; //Print a rand num
cout << temp2.num << endl; //Print 0
}

两者之间有什么区别?
temp temp1;


temp temp2 = temp();

最佳答案

temp temp1;

这将在名为 temp的实例上调用 temp1的默认构造函数。
temp temp2 = temp();

这会在临时对象上调用 temp的默认构造函数,然后以临时对象作为参数在 temp2上调用编译器生成的copy-constructor(当然,这假定编译器不忽略副本;这取决于编译器的优化设置)。

至于为什么要获得不同的初始化值,则该标准的第8.5节是相关的:

8.5初始化程序[dcl.init]

第5段:要对 T类型的对象进行零初始化意味着:
  • 如果T是标量类型(3.9),则将对象设置为0(零)的值,将其转换为T
  • (如果T是非联合类类型),则每个非静态数据成员和每个基类子对象都将初始化为零;
  • (如果T是联合类型),则对象的第一个命名数据成员将被零初始化;
  • 如果T是数组类型,则每个元素都初始化为零;
  • 如果T是引用类型,则不执行初始化。

  • 要默认初始化 T类型的对象意味着:
  • 如果T是非POD类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式错误);
  • 如果T是数组类型,则每个元素都是默认初始化的;
  • 否则,该对象将被零初始化。

  • 值初始化 T类型的对象的意思是:
  • 如果T是具有用户声明的构造函数(12.1)的类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);
  • 如果T是不具有用户声明的构造函数的非联合类类型,则T的每个非静态数据成员和基类组件都将被值初始化;
  • 如果T是数组类型,则每个元素都进行值初始化;
  • 否则,该对象将被零初始化。

  • 第7款:其初始化程序是一组空括号(即())的对象应进行值初始化。

    第9段:如果未为对象指定初始化程序,并且该对象是(可能是cv限定的)非POD类类型(或其数组),则该对象应进行默认初始化;否则,默认为初始化。如果对象是const限定类型,则基础类类型应具有用户声明的默认构造函数。否则,如果未为非静态对象指定初始化程序,则该对象及其子对象(如果有)具有不确定的初始值;否则,为false。如果对象或其子对象属于const限定类型,则程序格式错误。

    12个特殊成员功能[特殊]

    第7段:隐式声明的类的默认构造函数在用于创建其类类型(1.8)的对象时被隐式定义。隐式定义的默认构造函数执行该类的初始化集,该初始化集将由该类的用户编写的默认构造函数使用空的mem-initializer-list(12.6.2)和一个空的函数体执行。

    12.6.2初始化基础和成员[class.base.init]

    第4段:如果给定的非静态数据成员或基类未通过mem-initializer-id命名(包括由于构造函数没有ctor-initializer而没有mem-initializer-list的情况)
  • 如果实体是(可能是cv限定的)类类型(或其数组)或基类的非静态数据成员,并且实体类是非POD类,则该实体是默认初始化的(8.5)。如果实体是const限定类型的非静态数据成员,则实体类应具有用户声明的默认构造函数。
  • 否则,不初始化实体。如果实体是const限定类型或引用类型,或者是(可能是cv限定)POD类类型(或其数组)包含(直接或间接)const限定类型成员的程序,则该程序不适形成。


  • 因此,现在已经制定了规则,让我们看看它们如何应用:
    temp temp1;
    temp是非POD类型(因为它具有 std::string成员),并且由于没有为 temp1指定初始化程序,因此它将被默认初始化(8.5/9)。这将调用默认构造函数(8.5/5)。 temp具有一个隐式默认构造函数(12/7),该构造函数默认初始化 std::string成员,而 int成员根本未初始化(12.6.2/4)。
    temp temp2 = temp();

    另一方面,临时 temp对象是值初始化(8.5/7)的,它会值初始化所有数据成员(8.5/5),这将调用 std::string成员中的默认构造函数,并将零初始化 int成员(8.5/5)。

    当然,如果您不必在5个以上的不同地方引用该标准,只需确保您明确初始化所有内容即可(例如 int i = 0;或使用初始化列表)。

    关于c++ - C++默认构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5999522/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com