深入C++的默认构造函数2-成员变量有默认构造函数
2012-09-23 14:59
239 查看
在上一篇文章中,我们看了下简单的默认构造函数(没有成员变量的类)的构造函数的反汇编代码。这次我们来看一下如果一个类如果有默认构造函数的成员变量的话,这个类的默认构造函数会是什么样子。注:在这篇文章中的默认构造函数都是空的构造函数,就像下面代码的构造函数:
在开始看代码前,我们先思考下拥有成员变量(有默认构造函数)的类的构造函数的行为。首先我们想一下类的构造函数的作用。类的构造函数的作用是对这个类进行初始化(initialization),即为此类的实例分配内存等资源。这样的话,默认构造函数应该会自动调用成员变量的构造函数。那是不是这样呢,代码来验证。
示例代码:
反汇编的代码:
我们查看C::C () 的代码:
在反汇编的代码中可以看到,C的构造函数调用了A和B的默认构造函数。调用的A和B的顺序是和C中声明A、B的顺序是一致的。
看来结果和前面想的是一样的,再找些理论基础吧:
"如果class A 内含一个或一个以上的 member class objects, 那么 class A 的每一个constructor必须调用每一个 member class objects 的 default constructor"。编译器会扩张已存在的 constructors,在其中安插一些代码,使得 user code 在被执行之前,先调用必要的 default constructors. ” -----《深度探索C++对象模型》-P42。
这就是这次记录的东西了。嘿嘿,比起上次懒了,隔了好久才写这一篇。最近经历了不少东西,内心在骚动。以前想写博客是个很简单的事,写的时候才发现真心不是那回事。好好努力吧。
请大家多多指教,板砖尽管扔,不扔脸一切好说。
class A { public: A(){}; void print() { std::cout << "I am A" << std::endl; } };
在开始看代码前,我们先思考下拥有成员变量(有默认构造函数)的类的构造函数的行为。首先我们想一下类的构造函数的作用。类的构造函数的作用是对这个类进行初始化(initialization),即为此类的实例分配内存等资源。这样的话,默认构造函数应该会自动调用成员变量的构造函数。那是不是这样呢,代码来验证。
示例代码:
#include <iostream> class A { public: A(){}; void printA() { std::cout << "I am A" << std::endl; } }; class B { public: B(){}; void printB() { std::cout << "I am B" << std::endl; } }; class C { public: C(){}; void printC() { std::cout << "I am C" << std::endl; } private: A m_nA; B m_nB; }; int main() { C c; c.printC(); std::cin.get(); return 0; };
反汇编的代码:
C c; 00F814EE lea ecx,[c] 00F814F1 call C::C (0F81267h) c.printC(); 00F814F6 lea ecx,[c] 00F814F9 call C::printC (0F81271h) std::cin.get();
我们查看C::C () 的代码:
00F81560 push ebp 00F81561 mov ebp,esp 00F81563 sub esp,0CCh 00F81569 push ebx 00F8156A push esi 00F8156B push edi 00F8156C push ecx 00F8156D lea edi,[ebp-0CCh] 00F81573 mov ecx,33h 00F81578 mov eax,0CCCCCCCCh 00F8157D rep stos dword ptr es:[edi] 00F8157F pop ecx 00F81580 mov dword ptr [ebp-8],ecx 00F81583 mov ecx,dword ptr [this] 00F81586 call A::A (0F8126Ch) 00F8158B mov ecx,dword ptr [this] 00F8158E add ecx,1 00F81591 call B::B (0F81122h) 00F81596 mov eax,dword ptr [this] 00F81599 pop edi 00F8159A pop esi 00F8159B pop ebx 00F8159C add esp,0CCh 00F815A2 cmp ebp,esp 00F815A4 call @ILT+425(__RTC_CheckEsp) (0F811AEh) 00F815A9 mov esp,ebp 00F815AB pop ebp 00F815AC ret
在反汇编的代码中可以看到,C的构造函数调用了A和B的默认构造函数。调用的A和B的顺序是和C中声明A、B的顺序是一致的。
看来结果和前面想的是一样的,再找些理论基础吧:
"如果class A 内含一个或一个以上的 member class objects, 那么 class A 的每一个constructor必须调用每一个 member class objects 的 default constructor"。编译器会扩张已存在的 constructors,在其中安插一些代码,使得 user code 在被执行之前,先调用必要的 default constructors. ” -----《深度探索C++对象模型》-P42。
这就是这次记录的东西了。嘿嘿,比起上次懒了,隔了好久才写这一篇。最近经历了不少东西,内心在骚动。以前想写博客是个很简单的事,写的时候才发现真心不是那回事。好好努力吧。
请大家多多指教,板砖尽管扔,不扔脸一切好说。
相关文章推荐
- C++中父类成员变量和子类成员变量重复定义及访问方法的深入探究
- C++继承中成员变量关系及访问方法的深入探究
- C++使用初始化清单和直接在构造函数内初始化成员变量的区别
- 将成员变量声明为private和用非成员、非友友提高封装性(Effective C++_22、23))
- C语言中的static变量和C++静态数据成员
- C/C++基础问答(1):通过初始化列表和构造函数内赋值初始化成员变量的区别
- C++中成员变量加上static或const关键字后的分析
- c++ python交互之boost.python 简集之类成员变量设置
- C++成员变量的初始化顺序问题
- C++_类_不同类型成员变量的初始化方式
- 【转】C++成员变量的初始化顺序问题
- C++嵌套类及对外围类成员变量的访问
- C++中线程函数中方访问成员变量
- C++中各种类型的成员变量的初始化方法(mark-好)
- C++成员变量指针和成员函数指针
- C++深入理解(2)------新变量的认识
- C++面向对象—成员函数与成员变量的实现机制学习笔记(1)
- 深入探索C++对象模型之指向成员函数的指针
- C++成员变量的初始化顺序问题
- C/C++ 通过初始化列表和构造函数内赋值初始化成员变量的区别