栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

多态c++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多态c++

文章目录
    • 1.多态的定义及实现
    • 2.虚函数
    • 3. 析构函数的重写
    • 3. 抽象类
    • 4.多态的原理
    • 5.多继承中的虚函数表

1.多态的定义及实现

在继承中要构成多态还有两个条件:

  1. 必须通过基类的指针或者引用调用虚函数
  2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写
2.虚函数

虚函数:即被virtual修饰的类成员函数称为虚函数。

class Person
{
public: 
	virtual void BuyTicket() { cout << "买票-全价" << endl; }
};	

虚函数的重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型、函数名字、参数列表完全相同),称子类的虚函数重写了基类的虚函数。

class Person {
public:
 virtual void BuyTicket() { cout << "买票-全价" << endl; }
};
class Student : public Person {
public:
 virtual void BuyTicket() { cout << "买票-半价" << endl; }
3. 析构函数的重写

如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。虽然函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor。

class Commodity {
virtual ~Commodity() {}

private:

	long id;
	std::string name;
	double price; //商品数量 
	int num; //购买数量 
};


class NormalCommodity : public Commodity {
public:
	virtual ~NormalCommodity() {}

private:
	double discount;
};

class CommodityManage {
public:
	~CommodityManage()
	{
	for (auto e : pCommodities)
		delete e;
	}
private:
	std::vector pCommodities;
3. 抽象类

在虚函数的后面写上 =0 ,则这个函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。

class Commodity {
public:
	virtual int getType()const = 0; //纯虚函数 
}
4.多态的原理
class Base
{
public:
 virtual void Func1()
 {
 cout << "Func1()" << endl;
 }
private:
 int _b = 1;
 };
 
int main()
{
	cout << sizeof(Base) << endl;
	return 0;
}


为什么会产生这样的现象呢?

通过观察测试我们发现b对象是8bytes,除了_b成员,还多一个__vfptr放在对象的前面(注意有些,平台可能会放到对象的最后面,这个跟平台有关),对象中的这个指针我们叫做虚函数表指针。

如果是下面这种情况:虚函数表指针又会如何存储呢?

class Base
{
public:
	virtual void Func1()
	{
		cout << "Base::Func1()" << endl;
	}
	virtual void Func2()
	{
		cout << "Base::Func2()" << endl;
	}
	void Func3()
	{
		cout << "Base::Func3()" << endl;
	}
private:
	int _b = 1;
};
class Derive : public Base
{
public:
	virtual void Func1()
	{
		cout << "Derive::Func1()" << endl;
	}
private:
	int _d = 2;
};
int main()
{
	Base b;
	Derive d;
	return 0;
}

void test1(Base& b)
{
	b.Func1();
}

通过虚表指针指向的位置,调用对应的虚函数

5.多继承中的虚函数表
class Base1 {
public:
	virtual void func1() { cout << "Base1::func1" << endl; }
	virtual void func2() { cout << "Base1::func2" << endl; }
private:
	int b1;
};
class Base2 {
public:
	virtual void func1() { cout << "Base2::func1" << endl; }
	virtual void func2() { cout << "Base2::func2" << endl; }
private:
	int b2;
};
class Derive : public Base1, public Base2 {
public:
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func3" << endl; }
private:
	int d1;
};


d中有两个虚表指针分别指向从Base1和Base2继承的虚函数

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025328.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号