草庐IT

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

coder 2023-05-31 原文

给出以下代码:

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/

    有关c++ - C++默认构造函数的更多相关文章

    1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

      我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

    2. ruby - 默认情况下使选项为 false - 2

      这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

    3. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

      我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

    4. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

      我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

    5. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

      两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

    6. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

      我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

    7. ruby - 在 Ruby 中有条件地定义函数 - 2

      我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

    8. ruby - 在 Ruby 中按名称传递函数 - 2

      如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

    9. ruby - 使用 `+=` 和 `send` 方法 - 2

      如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

    10. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

      说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

    随机推荐