关于多态的讨论

封装、继承和多态是面向对象语言的三大特性,其中多态是最复杂、内容最多的特性,在这篇文章中,我们就来讨论一下多态的实现及原理。

所谓多态,就是同一个操作作用于不同对象时会产生不同的效果。比如说,汪星人会叫,喵星人也会叫,但是它们叫的声音是不同的。再比如我们打lol时,每个英雄都有Q,W,E,R四个技能,但不同的英雄在释放这四个技能时打出的效果是不一样的。多态可以分为静态多态和动态多态,我们先来看看动态多态。

动态多态可以通过虚函数和继承来实现,在C++中,我们可以定义父类的引用或指针,他们同样能够指向子类对象。上述特性确保了动态多态的实现。

#include<iostream>
#include<string>

using namespace std;


class Animal {
private:
	string name;
	string bark_type;        //叫声的类型
public:
	Animal() = default;
	Animal(string the_name, string the_bark_type) :name(the_name), bark_type(the_bark_type) {}
	//virtual string get_bark();
	virtual void bark();    //叫声函数
};

/*string Animal:: get_bark() {
	return this->bark_type;
}*/


void Animal::bark() {
	cout << "I can bark " << this->bark_type<< endl;
}

void my_bark(Animal *ptr) {
	ptr->bark();
}

//猫类
class Cat :public Animal {
private:
	string name;
	string bark_type;
public:
	Cat(string the_name, string the_type_bark) :name(the_name), bark_type(the_type_bark) {}
	void bark() override;
};

void Cat::bark() {
	cout << "I can bark " << this->bark_type << endl;
}


//狗类
class Dog :public Animal {
private:
	string name;
	string bark_type;
public:
	Dog(string the_name, string the_type_bark) :name(the_name), bark_type(the_type_bark) {}
	void bark() override;
};

void Dog::bark() {
	cout << "I can bark " << this->bark_type << endl;
}



int main() {
	Animal* p1 = new Dog("Trump","wang wang");//父类指针可以指向子类对象,引用也有相同的操作
	Animal* p2 = new Cat("Baden","miao miao");

	my_bark(p1);
	my_bark(p2);
	 
	delete(p1);
	delete(p2);
}

那么多态实现的原理又是什么?当我们创建一个一个类的对象时,同时也创建了一个虚函数表(由编译器实现),这个虚函数表中包括了该对象所属类的所有虚函数指针。那么对象时如何寻找这些虚函数的呢?在我们创建对象时,编译器不但为对象开辟了内存,同时还会增加一个vptr指针,他指向虚函数表的开头。当我们定义了一个指向某个实例的指针,比如指向Dog的p1, 之后我们调用bark函数时,p1所指的实例的vptr会优先从虚函数表中寻找bark虚函数,若存在则执行;若不存在,则像执行类中一般函数那样执行。p2同理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值