C++基础知识

1. 在构造函数当中一部分是初始化列表一部分是在花括弧里面,你能说一下这些的顺序是什么么?差别是什么 和this指针的顺序

构造函数会首先根据初始化列表中的值初始化对应的成员变量,当某个成员变量被初始化列表忽略时,会对其进行默认初始化。执行完这个过程之后才会执行花括弧中的构造函数体。花括弧中的构造函数体执行的都是赋值操作,而不是初始化操作。

初始化和赋值的区别事关底层效率问题:前者直接初始化数据成员,后者则先初始化再赋值,除了效率问题更重要的是,一些数据成员必须被初始化,例如,如果成员是const类型或者是引用类型或者成员属于某种类型且该类型没有定义默认构造函数时,就必须将其初始化。

2. 初始化列表的写法和顺序有没有什么关系?

没有。
初始化列表的写法和顺序没有关系,初始化列表只是说明用于初始化成员的值,而不限定初始化的具体执行顺序。成员的初始化顺序与他们在类定义中的出现顺序一致:第一个成员先被初始化,然后是第二个成员,依次类推。

3.虚继承

虚继承是让某个类做成声明,承诺愿意共享他的基类,共享的基类被称为虚基类,在这种机制下,不论虚基类在继承体系下出现多少次,在派生类中都只包含唯一一个共享的虚基类对象。

4. 子类在调用构造函数的时候 父类的构造过程
首先考虑没有继承关系时的构造过程:

1):分配内存
2):初始化列表之前先构造虚表指针,对虚表指针赋值(如果有虚函数才会进行这一步)
3):根据初始化列表中的值初始化对应的成员变量,当某个成员变量被初始化列表忽略时,会对其进行默认初始化。
4):执行构造函数体

一般的继承体系:

再考虑存在继承关系时的构造过程:
1):分配内存
2):先进行父类的构造,以父类的声明顺序为顺序,如果父类依然存在父类,就会先构造更早的父类,依次类推。如果父类位于初始化列表中,那么任何显示指定的参数都会被传递过去,如果没有位于初始化列表中,如果父类存在默认构造函数,就会调用这个默认构造函数,父类的构造过程同子类。(类似于递归的一个过程)
3):初始化列表之前先构造虚表指针,对虚表指针赋值
4):根据初始化列表中的值初始化对应的成员变量,当某个成员变量被初始化列表忽略时,会对其进行默认初始化。
5):执行构造函数体

虚继承体系:

和一般的继承体系有所区别,因为所有的派生类都共享唯一一个虚基类对象,所以虚基类对象的构造过程只能发生一次,这一次发生在最深层的派生类中,具体来讲,虚继承体系的每一层都会先条件式的测试传进来的某个参数,根据这个参数来判断是否调用虚基类的构造函数,具体的过程如下
1):分配内存
2):条件式的测试传进来的参数,根据这个参数来判断是否调用虚基类的构造函数,然后设置这个参数,使得继承体系更上一层的父类不会再调用虚基类的构造函数,所以虚基类对象的构造过程始终发生在最深层的派生类中。
3):进行父类的构造,以父类的声明顺序为顺序,如果父类依然存在父类,就会先构造更早的父类,依次类推。如果父类位于初始化列表中,那么任何显示指定的参数都会被传递过去,如果没有位于初始化列表中,如果父类存在默认构造函数,就会调用这个默认构造函数,父类的构造过程同子类。(类似于递归的一个过程)
4):初始化列表之前先构造虚表指针,对虚表指针赋值
5):根据初始化列表中的值初始化对应的成员变量,当某个成员变量被初始化列表忽略时,会对其进行默认初始化。
6):执行构造函数体

5. 描述一下,子类构造的时候,整个构造的过程,先怎么样,再怎么样,说清楚

同4

6. 是先构造父类的虚表指针还是先构造父类的成员?

先构造父类的虚表指针,再构造父类的成员

7. 虚表指针是什么时候设进去的?

在初始化列表之前构造虚表指针,在调用父类构造函数之后构造虚表指针。

8.虚表指针在初始化列表之前被赋值,可以放在初始化列表之后赋值吗?即顺序是:列表初始化、虚表指针赋值、构造函数体??
class B
{
public:
	virtual int size(){return 0;}
};


class A:public B{
public:
	int m_a; 
	A():m_a(size())   //在初始化列表中调用了虚函数(应该是A类的size()函数,不应该是B类的size()函数)
	{
		cout<<m_a<<endl;
	}
	virtual int size(){
		//cout<<2<<endl;
		return 1;}
};

int main()
{
	A a;
	return 0;
}

解答:如上述代码,如果虚表指针的初始化在初始化列表之后的话,可能会出现如上代码所示的情况:也就是说,在初始化列表中使用了一个虚函数!!!
那么在调用此虚函数的时候,应该访问哪个虚表呢?是基类的虚表?还是当前类的虚表?

毫无疑问,应该是当前类的虚表!!!
但是在调用此虚函数的时候,虚表指针并未赋值为子类的虚表,所以无法访问当前类的虚函数,访问的依旧是基类的虚函数。

因此,将虚表指针的赋值过程应该放置在初始化列表之前,这是为了防止在初始化列表出现调用虚函数的情况!!!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值