C ++类必须具有构造函数

电脑杂谈  发布时间:2020-07-29 12:02:54  来源:网络整理

c   类 static 函数_笔记本产品a类b类c类_c++类构造函数

1: 如果任何类未定义默认构造函数,它将被合成吗?

2: 综合的默认构造函数将显式设置类中每个成员的值?

3: 如何证明?

如果您对1、2的回答为否,请跳过阅读,以​​免浪费时间

实际上,问题1和2的答案不一定是. C ++标准写道,默认构造函数在需要时由编译器综合. 这里的重点是需要而不是必要性. 以程序示例为例:

#include

#include

使用命名空间标准;

A级

{

公共:

char * ptr;

// string str;

};

int main()

{

A b;

b.ptr = NULL;

c   类 static 函数_笔记本产品a类b类c类_c++类构造函数

返回0;

}

这个程序本身没有什么可谈的,可以谈论的是它的汇编代码. 调试时的汇编代码如下:

11: {

00401030推送ebp

00401031 mov ebp,esp

00401033 sub esp,44h

00401036推ebx

00401037 push esi

00401038推送edi

00401039 lea edic++类构造函数,[ebp-44h]

0040103C mov ecx,11h

00401041 mov eax,0CCCCCCCCh

00401046 rep stos dword ptr [edi]

12: A b;

13: b.ptr = NULL;

00401048 mov dword ptr [ebp-4],0

14: 返回0;

c   类 static 函数_笔记本产品a类b类c类_c++类构造函数

0040104F xor eax,eax

15: }

您能找到调用构造函数的地方吗,即A :: A(),:),找不到它,因为根本没有构造函数,此类等效于整数变量(类似在存储上,在用法上有所不同),它的空间是4个字节的堆栈ebp + 4此处

在程序注释中

// string str;

删除,再次进入程序集查看,代码如下:

10: int main()

11: {

00401070推送ebp

00401071 mov ebp,esp

00401073 sub esp,58h

00401076推ebx

00401077 push esi

00401078推送edi

00401079 lea edi,[ebp-58h]

0040107C mov ecx,16h

00401081 mov eax,0CCCCCCCCh

00401086 rep stos dword ptr [edi]

c++类构造函数_笔记本产品a类b类c类_c   类 static 函数

12: A b;

00401088 lea ecx,[ebp-14h]

0040108B呼叫@ ILT + 15(A :: A)(00401014)

13: b.ptr = NULL;

00401090 mov dword ptr [ebp-14h],0

14: 返回0;

00401097 mov dword ptr [ebp-18h],0

0040109E lea ecx,[ebp-14h]

004010A1呼叫@ ILT + 30(A ::〜A)(00401023)

004010A6 mov eax,dword ptr [ebp-18h]

15: }

看,我们的构造函数出现A: A():),为什么会出现?

由于该类中有一个名为string的类,我们跟踪发现该字符串类是在include / xstring中定义的,其形式如下:

typedef basic_string

字符串;

这是模板类,属于STL的类别. 如果您不相信我c++类构造函数,请查看SGI STL源代码. 如果有机会,请按照教学跟踪进行操作. 您会发现basic_string具有一系列构造函数,如下所示:

显式basic_string(const _A&_Al = _A())

: 分配器(_Al){_Tidy(); }

c++类构造函数_笔记本产品a类b类c类_c   类 static 函数

basic_string(const _Myt&_X)

: 分配器(_X.allocator)

{_ Tidy(),assign(_X,0,npos); }

basic_string(const _Myt&_X,size_type _P,size_type _M,

const _A&_Al = _A())

: 分配器(_A1){_Tidy(),分配(_X,_P,_M); }

basic_string(const _E * _S,size_type _N,

const _A&_Al = _A())

: 分配器(_Al){_Tidy(),assign(_S,_N); }

basic_string(const _E * _S,const _A&_Al = _A())

: 分配器(_Al){_Tidy(),assign(_S); }

basic_string(size_type _N,_E _C,const _A&_Al = _A())

: 分配器(_Al){_Tidy(),assign(_N,_C); }

实际上,重要的是第一个构造函数,因为在这里被称为将构造内存分配管理器分配给basic_string: )

了解,这是因为在类中有一个字符串类的对象. 别人属于你. 其他人有自己的构造函数. 您需要为其分配一个初始值. 您无能为力,因此编译器只需合成一个默认构造函数,在字符串中调用该构造函数,并为字符串对象设置初始状态

构造函数不一定存在,并且类中某些内置类型的默认构造函数不会为其设置默认值. 如果您不相信,请再次查看程序集,ptr的分配在哪里: )

在四种情况下,编译器将合成默认构造函数

1: 具有默认default / constructor函数的成员类对象

2: 具有默认/构造函数的基类对象

3: 具有虚函数的类

4: 继承虚拟基类的类

您可以参考本书的第2章“对C ++对象模型的深入理解”进行下载


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-288943-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 周康王姬钊
        周康王姬钊

      • 龙世宁
        龙世宁

        “天下没有人靠炒股发财”说的绝对了

      热点图片
      拼命载入中...