【C++】继承和多态[1]

C++的三大特性:继承、多态、封装

这篇博客讨论下继承和多态

继承

继承的本质是代码复用。

继承了什么: 

除构造函数和析构函数以外的所有成员

继承了作用域

继承写法:

类标识 类名:继承方式  基类名

继承和派生的关系:

 

派生类的内存布局:

派生类对象的构造和析构:

构造:

1、系统调用基类的构造

2、系统调用派生类的构造

析构:

1、系统调用派生类的析构

2、系统调用基类的析构

基类中不同访问限定符下的成员以不同继承方式继承后在派生类中的访问限定

public:任意位置访问

private:本类类中访问

protected:本类、子类类中访问

类和类的关系:

组合:a part of  has_a

继承:a kind of  is_a

代理:迭代器

同名函数的关系:

重载:(重定义)    三要素: 同名    不同参数   同作用域

隐藏:派生类中隐藏了基类中所有的同名函数    1、同名    2、不同作用域

#include<iostream>

class Base
{
public:
	Base(int b):mb(b)
	{}
	void Show()
	{
		std::cout<<"Base::"<<mb<<std::endl;
	}
private:
	int mb;
};

class Derive:public Base
{
public:
	Derive(int d):md(d),Base(d){}
	void Show()
	{
		std::cout<<"Derive::"<<md<<std::endl;
	}
private:
	int md;
};

int main()
{
	Base *p = new Derive(10);
	p->Show();
	return 0;
}

调用了基类的Show函数,子类将父类的Show函数隐藏了,静态调用

覆盖:(重写)派生类中的虚函数覆盖基类中同名同参的虚函数(发生在续表合并过程中)

1、同名同参2、不同作用域3、都为虚函数

#include<iostream>

class Base
{
public:
	Base(int b):mb(b)
	{}
	virtual void Show()
	{
		std::cout<<"Base::"<<mb<<std::endl;
	}
private:
	int mb;
};

class Derive:public Base
{
public:
	Derive(int d):md(d),Base(d){}
	void Show()
	{
		std::cout<<"Derive::"<<md<<std::endl;
	}
private:
	int md;
};

int main()
{
	Base *p = new Derive(10);
	p->Show();
	return 0;
}

调用了子类的Show函数,子类将基类的Show函数覆盖了,动态调用

基类和派生类指向或引用的相互指向或引用:

允许基类指针或引用  指向或引用派生类对象,反之,不允许

 

多态

多态:同一接口不同形态

多态的本质:接口复用

静多态:编译期间    函数重载 模板

动多态:运行期间

宏多态:预编译

静态绑定又称早绑定

动态绑定又称晚绑定

class Base
{
public:
	Base(int a) :ma(a)
	{
		//this->Show();
		std::cout << "Base::Base()" << std::endl;
	}
	virtual void Show()
	{
		std::cout << "Base::ma:" << ma << std::endl;
	}
	void Show1()
	{
		Show();
	}
	virtual ~Base()
	{
		//Show();
		//Show1();
		std::cout << "Base::~Base()" << std::endl;
	}
protected:
	int ma;
};
class Derived :public Base
{
public:
	Derived(int b) :mb(b), Base(b)
	{
		std::cout << "Derived::Derived()" << std::endl;
	}
	void Show()
	{
		std::cout << "Derived::mb:" << mb << std::endl;
	}
	~Derived()
	{
		std::cout << "Derived::~Derived()" << std::endl;
	}
private:
	int mb;
};

int main()
{
	Base* pb1 = new Base(10);
	pb1->Show();//动多态

	Base* pb2 = new Derived(10);
	pb2->Show();//动多态

	Derived* pd1 = new Derived(10);
	pd1->Show();//动多态

	Base b(10);
	Derived d(20);

	Base& rb1 = b;
	Base& rb2 = d;

	rb1.Show();//动多态
	rb2.Show();//动多态

	Derived& rd1 = d;
	rd1.Show();//动多态

	b.Show();//静多态
	d.Show();//静多态
	return 0;
}

动多态的发生条件:

     指针或引用调用虚函数   对象完整

 

 

当类中方法被virtual关键字修饰时,系统会生成一个虚函数指针(vfptr),为虚函数指针维护一个虚函数表(vftable):

虚表的写入时机:构造函数的第一行代码执行之前

基类的指针指向派生类对象  指向的是派生类对象中基类的起始位置

 

 

判断函数是否能成为虚函数:是否满足:1、能取地址    2、依赖对象调用

析构函数

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的继承多态和虚函数是面向对象编程的重要概念。 继承是指一个类可以从另一个继承属性和方法。子类可以继承父类的公有成员和保护成员,但不能继承私有成员。通过继承,子类可以重用父类的代码,并且可以添加自己的特定功能。继承可以实现代码的重用和层次化的设计。 多态是指同一个函数可以根据不同的对象调用不同的实现。多态可以通过虚函数来实现。虚函数是在基类中声明为虚拟的函数,它可以在派生类中被重写。当通过基类指针或引用调用虚函数时,实际调用的是派生类中的实现。这样可以实现动态绑定,即在运行时确定调用的函数。 虚函数的原理是通过虚函数表来实现的。每个包含虚函数的类都有一个虚函数表,其中存储了虚函数的地址。当调用虚函数时,编译器会根据对象的类型在虚函数表中查找对应的函数地址并调用。 综上所述,C++中的继承多态和虚函数是实现面向对象编程的重要机制,它们可以提高代码的灵活性和可扩展性。 #### 引用[.reference_title] - *1* *3* [C++多态之 虚函数和虚函数表](https://blog.csdn.net/weixin_46053588/article/details/121231465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [c++多态及虚函数表内部原理实战详解](https://blog.csdn.net/bitcarmanlee/article/details/124830241)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值