
1: 如果任何类未定义默认构造函数,它将被合成吗?
2: 综合的默认构造函数将显式设置类中每个成员的值?
3: 如何证明?
如果您对1、2的回答为否,请跳过阅读,以免浪费时间
实际上,问题1和2的答案不一定是. C ++标准写道,默认构造函数在需要时由编译器综合. 这里的重点是需要而不是必要性. 以程序示例为例:
#include
#include
使用命名空间标准;
A级
{
公共:
char * ptr;
// string str;
};
int main()
{
A b;
b.ptr = NULL;

返回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;

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]

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(); }

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
“天下没有人靠炒股发财”说的绝对了