继承与多态的相关题目

1.派生类内存布局,继承了基类什么东西?

先是基类,后是派生类,并且继承了名字作用域和除析构构造之外的所有方法

2. 类的编译程顺序,构造顺序,析构顺序

类的编译程序:先编译类名->成员名->方法体

子类的构造顺序:先构造父类,在构造子类

子类的析构顺序:先析构子类,后析构父类,即先构造的后析构,后构造的先析构

3.基类派生类同名成员之间的关系

重载:重载是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同

<1>作用域相同

<2>函数名相同

<3>参数列表不同

隐藏:子类会隐藏父类方法中同名的方法

覆盖:子类中和父类中一样的(同返回值,同参数列表,同名)虚成员方法构成覆盖

4.四种类型强转

  • const_cast
  • static_cast
  • dynamic_cast
  • reinpreter_cast

5.虚表什么时候产生?存放在哪里?

在编译时期产生,存放在.rodata段

6.纯虚函数->抽象类(抽象类不能定义对象,只能定义指针引用)

virtual void bark() = 0;不提供实现,派生类可以自己写实际的函数,虚基类不能构造函数

7.动多态,静多态

静多态:编译时期决定的多态,如:模板,重载

动多态:运行时期决定的多态,如:继承中的多态

动多态调用的条件有什么?

<1>指针调用或者引用调用

<2>该类型下的虚函数

<3>对象完整

8.基类指针指向子类对象,指针是什么类型?*指针是什么类型?(基类中有虚函数)

class A
{
public:
	virtual void show()
	{
		cout << "A" << endl;
	}
};

class B :public A
{ 
	void show()
	{
		cout << "B" << endl;
	}
};

int main()
{
	A *a = new B();

	cout << typeid(a).name() << endl;    //结果是class A *
	cout << typeid(*a).name() << endl;   //结果是 class B
	return 0;
}

定义了一个基类的指针,指向父类的对象,结果如上所示,指针类型是class A * ,*a的类型是class B

9.基类中存在虚函数,子类就会覆盖基类中和子类同名的虚函数,子类的内存布局

 

10.基类无虚函数,子类有虚函数。将基类指针指向子类的对象时,其指向子类对象中基类起始的部分。

11.基类定义虚函数和普通重载函数,子类定义同名函数隐藏普通函数

class Base
{
public:

	//这两个函数构成重载
	void show()
	{
		cout << "Base::void show()" << endl;
	}
	virtual void show(int i)
	{
		cout << "virtual void show(int i )" << endl;
	}
};

class Derive :public Base
{ 
	//隐藏父类中的void show函数
public:
	void show()
	{
		cout << "Derive::void show()"  << endl;
	}
};

int main()
{
	Base *base = new Base();
	Derive *derive = new Derive();
	base->show();
	base->show(10);
	derive->show();
	derive->Base::show();
	return 0;
}

12

.基类指针指向堆上的子类对象,此时delete指针,子类析构函数未调用,有可能造成内存泄漏。基类析构函数应该写成虚函数

13.基类构造清除所有数据,基类指针调用自己的虚函数,子类调用虚函数

class Base
{
public:

	Base()
	{
		memset(this, 0, sizeof(Base));
	}
	virtual void show()
	{
		cout << "virtual void show()" << endl;
	}
};

class Derive :public Base
{ 
public:
	Derive()
		:Base()
	{

	}
	void show()
	{
		cout << "Derive::void show()"  << endl;
	}
};

int main()
{
	Base *base = new Base();
	//base->show();  error

	Derive *derive = new Derive();
	derive->show();


	return 0;
}

基类的对象在调用show函数的时候会执行出错,当基类构造的时候将空间内所有字节都置为0,包括vfptr,当访问虚函数的时候就会进入地址位0的空间,访问出错;子类对象在调用show函数的时候会正常执行,虽然基类构造的时候将空间内所有字节包括vfptr都置为0,但是子类在构造的时候将vfptr又置为自己的show函数入口地址,因此访问正常

14.基类和派生类的构造函数、析构函数中调用虚函数不会产生多态调用。因为对象不完整,只要在构造函数之后到析构函数之前对象才是完整的。

15.基类虚函数放到共有,派生类虚函数放到私有,外部基类指针指向子类对象,能否派生类私有函数访问?

可以,该指针是基类的指针,但是又指向子类的示例,在调用之前无法确定调用的究竟是谁

16.基类和子类给不同的虚函数传参数默认值,定义基类指针指向子类对象,调用函数,此时会调用子类的函数,但是函数的参数默认值是基类的参数默认值。

class Base
{
public:

	 virtual void show(int a= 20)
	{
		cout <<a << "0000000000000000000"<< endl;
	}
};

class Derive :public Base
{ 
public:

	void show(int a = 30000)
	{
		cout << a << endl;
	}
};

int main()
{
	Base *base = new Derive();
	base->show();
	
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值