再问默认构造函数
如果一个类中没有定义任何的构造函数,那么编译器只有在以下三种情况,才会提供默认的构造函数: a、如果类有虚拟成员函数或者虚拟继承父类(即有虚拟基类)时;
b、如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数);
c、在类中的所有非静态的对象数据成员,它们对应的类中有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)。
==============================================================================================================
上面的话引自一篇博客,另外在《VC++深入详解》中见到同样的话,我对“b、如果类的基类有构造函数(可以是用户定义的构造函数,或编译器提供的默认构造函数)”话不解,(其它的由于技术不怎么样还不知道如果来测试),为了检验这段话的正确性,我做了如果下的测试
#include <iostream>
using namespace std;
class A
{
};
void main ()
{
A a;
}这段代码对应的汇编代码如下:
00401030 push ebp
00401031 mov ebp,esp
00401033 sub esp,44h
00401036 push ebx
00401037 push esi
00401038 push edi
00401039 lea edi,[ebp-44h]
0040103C mov ecx,11h
00401041 mov eax,0CCCCCCCCh
00401046 rep stos dword ptr [edi]
21: A a;
22: }
00401048 pop edi
00401049 pop esi
0040104A pop ebx
0040104B mov esp,ebp
0040104D pop ebp
0040104E ret在这段代码中,我们确实没看到call指令,也就是说并没有产生构造函数,那么我的问题是,如果没有构造函数,那么为什么又可以产生对象a?
Question2:先看下面的这个代码:
//代码2.cpp
#include <iostream>
using namespace std;
class A
{
};
class B:A
{
public:
B()
{
cout<<"B is constructed"<<endl;
}
};
void main ()
{
B b;
}上面的代码对应下面的汇编代码
00401170 push ebp
00401171 mov ebp,esp
00401173 sub esp,44h
00401176 push ebx
00401177 push esi
00401178 push edi
00401179 lea edi,[ebp-44h]
0040117C mov ecx,11h
00401181 mov eax,0CCCCCCCCh
00401186 rep stos dword ptr [edi]
17: B b;
00401188 lea ecx,[ebp-4]
0040118B call @ILT+80(B::B) (00401055)
18: }
00401190 pop edi
00401191 pop esi
00401192 pop ebx
00401193 add esp,44h
00401196 cmp ebp,esp
00401198 call __chkesp (00409050)
0040119D mov esp,ebp
0040119F pop ebp
004011A0 ret在汇编代码中我们仅可以看到0040118B call @ILT+80(B::B) (00401055)这们一句call指令,并没有看到相关的A的构造指令,但是由继承的原理我们知道要产生子类,必须先构造父类,这不就矛盾了。从以上给出的那三个条件说,“如果类的基类有构造函数”,这里我们也没给类A添加构造函数,而且代码2.cpp中,类A要产生构造函数的条件也不符合上面说的三条中的任何一条,如果按上面的三条为标准的话,那么类A也就没了默认构造函数,那么当定义子类的实例时,子类的构造函数会去找父类的构造函数先构造父类,这时无法找到,但是代码是可以通过编译的。这又是为什么?当然你也许会说你用VC6.0是可以通过编译的,但是我用VS2010也是可以通过编译的。下面说下我的测试环境
OS:win7 旗舰 32位系统
编译环境:vc6.0,vs2010(都试过)
相关推荐
C++默认构造函数的问题
C++ defaul construct :缺省构造函数(默认构造函数) 定义:第一种 构造函数没有参数,即是 A()形式的 第二种 构造函数的全部参数由缺省值提供,A(int a=0,int b=0) 编译器添加的默认构造函数的条件: 如果创建一个类你没有写任何构造函数,则系统会自动生成默认的无参构造函数,函数为空,什么都不做(这只是一种情况而言,此构造函数是trival 派生类和基类的关系: 我们通常说的派生类和基类,我们调用派生类的自定义的构造函数的时候,派生类会自动调用基类中的default construct函数,而不能调用基类中的其他构造函
对C++默认构造函数的一点重要说明
大多数C++书籍都说在我们没有自己定义构造函数的时候,编译器会自动生成默认构造函数。其实这句话我一直也是 深信不疑。但是最近看了一些资料让我有了一点新的认识。 其实我觉得大多数C++书籍之所以这样描述其实是玩了文字游戏的。如果说编译器自动产生的默认构造函数对于我们 的类没有任何作用,也就是说在编译器默认生成的这个构造函数里根本没有任何实质性的代码工作,那么这种默认构 造其实是可有可无的,所以不妨说编译器其实是为每个类生成了默认构造函数的。 在深度探索C++对象模型中讲了四种关于编译器自动生成默认构造函数的情况,在这四种情况下生成的默认构 造函数里面是由实质的隐含代码操作的: 1、 如果类A成员
c#默认构造函数的作用
c#默认构造函数的作用
C++ 默认构造函数
C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数C++ 默认构造函数
解析C++中构造函数的默认参数和构造函数的重载
C++构造函数的默认参数 和普通函数一样,构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,即如果用户不指定实参值,编译系统就使形参取默认值。 【例】 #include using namespace std; class Box { public : Box(int h=10,int w=10,int len=10); //在声明构造函数时指定默认参数 int volume( ); private : int height; int width; int length; }; Box::Box(int h,int w,int


