c++学习(多态)

多态

#include<iostream>
using namespace std;

class Animal {
public:
	virtual void speak() {//虚函数
		cout << "animal speak" << endl;
	}
	//virtual ~Animal() {//虚析构函数为了解决子类某些属性创建在堆区无法释放的问题
	//};
	virtual ~Animal()=0;//纯虚析构函数,还需要在外部实现
};
Animal:: ~Animal() {
}
/*
静态多态:函数重载、运算符重载
动态多态:派生类和虚函数实现运行多态
*/
class cat :public Animal {
public:
	cat(string name) {
		m_name = new string(name);
	}
	void speak() {
		cout << "cat speak" << endl;
	}

	~cat() {
		if (m_name!=NULL)
		{
			cout << "cat 析构" << endl;
			delete m_name;
			m_name = NULL;
		}
	}
	string* m_name;
};

/*
动态多态函数地址晚绑定——在运行阶段确定函数地址
静态多态函数(静态成员函数)--编译阶段就绑定了地址
动态多态使用满足条件:
1.存在继承关系
2.子类重写父类虚函数
*/

/*
动态多态的原理:
加上virtual之后,父类就有vfptr(虚函数指针)这个指针,指向vftable,(这个vftable中存放的就是Animal中speak的函数地址)
如果子类没有重写speak函数,那么子类中的vfptr中的vftable中存放的是父类的speak函数地址,因为是继承过来的。
但是当子类重写这个函数之后,子类中的vftable中存放的就是子类重写之后speak的函数地址了,所以这就是多态。
*/
void dospeak(Animal& animal) {//父类与子类不需要强制类型转换,他们之间是可以自动转换的,后续调用:Animal& animal=cat,满足使用条件
	animal.speak();
}


//设计一个计算类,采用多态的方式
class AbstractCalculator {//设计一个抽象计算类
public:
	virtual int getresult() {//在之后的使用中,父类中的函数基本没有使用,因此可以写成纯虚函数的形式
		/*
		virtual int getresult()=0; 
		只要有1个纯虚函数,那么这个类就是抽象类了
		抽象类:
		1.无法实例化对象
		2.如果继承子类必须重写虚函数,否则那么子类也是抽象类
		所以使用多态技术,可以采用纯虚函数和抽象类的形式
		*/
		return 0;
	}

	int num1;
	int num2;
};
class AddCalculator:public AbstractCalculator {

	int getresult() {
		return num1 + num2;
	}
};

class SubCalculator :public AbstractCalculator {
public:
	int getresult() {

		return num1 - num2;
	}
};
void test() {
/*动态多态使用满足条件:
1.存在继承关系
2.子类重写父类虚函数

动态多态使用:
父类的指针 或引用 指向子类对象
*/
	AbstractCalculator* abc = new AddCalculator;
	abc->num1 = 20;
	abc->num2 = 30;
	cout << abc->num1 << "+" << abc->num2 << "=" << abc->getresult() << endl;
}
int main()
{
	cat cat1("tom");
	dospeak(cat1);
	test();

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值