C++的继承和派生(四)多态的实现和虚函数

  • C++的多态有四种:

    1、重载多态:函数重载和运算符重载(后面讲解)
    2、强制多态:强制类型转换
    3、包含多态:利用虚函数实现,在子类中重写函数,实现动态绑定
    4、参数多态:与类模板相关联(后面讲解)

本篇所要讲解的是包含多态,由于是在继承的基础上实现的,所以就干脆放在继承和派生这一专题了

在介绍多态前,请看下面一段代码

class Dog  {
public:

	void run() {
		cout << "Dog-run()" << endl;
	}
	void speak() {
		cout << "Dog-speak()" << endl;
	}
};

class Pig{
public:
	void run() {
		cout << "Pig-run()" << endl;
	}
	void speak() {
		cout << "Pig-speak()" << endl;
	}
};

class Cat {
public:
	void run() {
		cout << "Cat-run()" << endl;
	}
	void speak() {
		cout << "Cat-speak()" << endl;
	}
};

void Display(Dog* p) {
	p->run();
	p->speak();
}

void Display(Pig* p) {
	p->run();
	p->speak();
}

void Display(Cat* p) {
	p->run();
	p->speak();
}

int main() {
	Display(new Dog());
	Display(new Pig());
	Display(new Cat());
	
	getchar();
	return	0;
}

运行结果

Dog-run()
Dog-speak()
Pig-run()
Pig-speak()
Cat-run()
Cat-speak()
  • 代码分析:
    1、上面的代码中自定义三个类,三个类中都有相同的成员函数(这三个类有共同的属性),但是这些函数都执行了不同的功能,虽然最终可以实现各个类中的成员函数的功能,但是当这样的类很多的时候,代码写起来就很繁琐。而且可不可以将这三个类的共同属性抽象出来,作为他们的父类呢?
    2、父类指针和子类指针:我们都知道,在继承中(public),父类指针可以指向子类对象是安全的(反过来是不安全的)。但是,此时父类指针只能访问派生类的成员变量,并不能访问其成员函数

为了解决这个问题,C++增加了虚函数,就是在父类的成员函数声明前增加关键字 virtual ,用 virtual修饰的函数成为虚函数

此时改写后的代码如下

class Animal {	//增加了一个父类Animal
public:
	//虚函数
	virtual void run() {
		cout << "Animal-run()" << endl;
	}
	virtual void speak() {
		cout << "Animal-speak()" << endl;
	}
};

class Dog:public Animal {
public:
	//重写
	void run() {
		cout << "Dog-run()" << endl;
	}
	void speak() {
		cout << "Dog-speak()" << endl;
	}
};

class Pig:public Animal {
public:
	void run() {
		cout << "Pig-run()" << endl;
	}
	void speak() {
		cout << "Pig-speak()" << endl;
	}
};

class Cat:public Animal  {
public:
	void run() {
		cout << "Cat-run()" << endl;
	}
	void speak() {
		cout << "Cat-speak()" << endl;
	}
};

void Display(Animal* p) {
	p->run();
	p->speak();
}

int main() {

	Display(new Dog());
	Display(new Pig());
	Display(new Cat());

	getchar();
	return	0;
}

运行结果

Dog-run()
Dog-speak()
Pig-run()
Pig-speak()
Cat-run()
Cat-speak()

总结

  • 构成多态的要素
    1、子类重写父类的成员函数
    2、父类指针指向子类对象
    3、派生类中要有虚函数重写
    4、利用父类指针调用重写的成员函数

  • 什么时候要声明虚函数
    首先看成员函数所在的类是否会作为基类,然后看成员函数在类的继承后有无可能被更改功能,如果希望将其更改为其他功能,一般将他声明为虚函数,否则不需要

  • 注意事项
    1、只要将父类中的成员函数声明为虚函数,则其所有的派生类中同名的函数都将自动成为虚函数,所以子类的重写的成员函数就可以不用加关键字 virtual
    2、如果派生类没有定义新的函数来重写父类的虚函数,则将使用父类的虚函数
    3、构造函数不能是虚函数,因为派生类不能够继承父类的构造函数,但是析构函数可以

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值