C++中必须知道的问题——转

转http://blog.chinaunix.net/uid-26611383-id-3513289.html


1.静态成员函数为什么不能声明为const

2.当一个父类对象以其子类对象初始化时会发生什么
3.一个类的对象所占内存是由什么决定的
4.构造函数初始化列表的作用
5.为什么最好不要在构造函数和析构函数中调用虚函数
6.虚函数表是怎么回事
7.虚函数指针vptr存在于一个对象的什么位置,其作用是什么
8.一个string对象的数据成员占多少内存
9.一个空类的对象占几个字节
10.通过指针存取一个对象的数据成员和通过对象直接存取其数据成员有什么区别
11.什么时候会调用拷贝构造函数,什么时候又会调用赋值运算符?
12.构造函数为什么不能声明为虚函数



答案:
1.普通成员函数声明为const是防止函数修改调用该成员函数的对象的数据成员,这个对象时通过this指针隐式传递给该函数的
,而静态成员函数没有this指针,所以就没有这项功能,也就不需要声明为const

2.子类对象的数据成员包含继承自父类的数据成员和子类本省的数据成员两部分,所以用子类对象赋值给父类对象时会发生切割行为,即初始化的父类只会存在子类对象的父类数据成员部分

3.一个类的对象所占内存是由其数据成员(包括继承自父类的数据成员和自己本身的数据成员两部分)加上其虚函数指针(如果存在虚函数)

4.使用初始化列表的构造函数显式的初始化类的成员;而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化

初始化列表的作用是初始化而不是赋值,免去了构造对象然后调用operator=的过程,所以效率更高一点(对于内置类型或者简单类型这个并不明显)


5. 实例化一个派生类对象时,首先调用父类构造函数,此时派生类部分的成员变量还没有初始化,如果虚函数下降到派生类级,会发生不可预知的行为

6. C++ 中当一个类中存在 virtual 函数(虚函数)或者它的父类中存在虚函数,那么编译器就会为这个类生成虚函数表( virtual table ),虚函数表中存放着虚函数的地址,含有虚函数的类或者其子类的对象编译器都为其加上一个虚函数指针vptr,vptr在执行时指向对应的虚函数,从而实现多态

7.vptr一般的编译器会将其放在对象所占内存空间的最前面的部分,vptr的作用就是指向虚函数表存放的函数


8.要解答这个问题就要清楚string类的实现,一个string对象的数据成员包括存放该string的地址的指针,还有该string的长度两部分,即:4+strlen(str)+1


9.一个空类为1个字节,可能会因为编译器不同而有所不同,这一个字节是为了定位这个空类的对象,反过来思考会比较容易理解,我们假设空类对象不占内存,那么系统怎么区分这个空类的若干个对象呢?因为普通类(非空类)的对象都占据一定的内存空间,所以系统可以唯一的确定他们并调用他们相应的成员函数,那么为什么是1个字节,而不是2个,3个或者更多呢,当然是1个字节就可以定位空类的对象了,多的话岂不是浪费

10.当要存取的数据成员是从虚基类继承过来时,通过指针不能确定这个指针具体指向哪个对象,存取只能延迟到执行期间,而通过对象存取,在编译期间就已经确定了该数据成员相对于该对象的偏移,所以用对象存取效率更高,如果不存在虚基类,那么两种方式完全一样


11.在一个新对象被创建时用另一个对象初始化该对象一定会调用拷贝构造函数,因为新对象的创建一定会调用构造函数,如果不存在新对象的创建那么就会调用赋值运算符

12.构造函数是分配内存的行为,虚函数需要通过虚函数表虚函数指针来调用,在构造函数之前,这些都还没有初始化,所以也就无从调用,所以构造函数不能为虚函数(对象还没实例化,内存中还没有空间,哪来的虚表?没有虚表哪来的虚函数?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值