#include <iostream> using namespace std; class FlyBehavior { public: virtual void fly() = 0; }; class FlyWithWings : public FlyBehavior { public: virtual void fly() { cout << "I'm flying!!" << endl; } }; class FlyNoWay : public FlyBehavior { public: virtual void fly() { cout << "I can't fly" << endl; } }; class QuackBehavior { public: virtual void quack() = 0; }; class Quack : public QuackBehavior { public: virtual void quack() { cout << "Quack" << endl; } }; class MuteQuack : public QuackBehavior { public: virtual void quack() { cout << "silence" << endl; } }; class Squeak : public QuackBehavior { public: virtual void quack() { cout << "squeak" << endl; } }; class Duck { public: FlyBehavior* flyBehavior; QuackBehavior* quackBehavior; virtual void display() = 0; void performFly() { flyBehavior->fly(); } void performQuack() { quackBehavior->quack(); } void swim() { cout << "All ducks float, even decoys!" << endl; } }; class MallardDuck : public Duck { public: MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); } virtual void display() { cout << "I'm a real Mallard duck" << endl; } }; int main() { Duck* mallard = new MallardDuck(); mallard->performQuack(); mallard->performFly(); return 0; }
遇到的问题主要是:
1. 重载函数和虚函数,概念不同,虚函数用于多态,重载函数中,函数的返回类型,参数个数至少有一个不同。
2. c++中虚函数要么定义其函数体,要么设置为纯虚函数,否则编译会出现错误。
一下是转载的关于重载和虚函数的区别。
重载函数,重载可以看作是静态的多态。函数重载的返回类型及所带的参数必须至少有一样不完全相同,只需函数名相同即可。
基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同。
重载虚函数时,若与基类中的函数原型出现不同,系统将根据不同情况分别处理:
(1)仅仅返回类型不同,其余相同,系统会当作出错处理;
(2)函数原型不同,仅仅函数名相同,系统会认为是一般的函数重载,将丢失虚特性。
当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。
派生类构造函数的调用次序有三个原则:
1) 虚基类的构造函数在非虚基类之前调用;
2) 若同一层次中包含多个虚基类,这些虚基类的构造函数按它们说明的次序调用;
3) 若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类的构造函数。
重载函数在类型和参数数量上一定不相同,而重定义的虚函数则要求参数的类型和个数、函数返回类型相同;
虚函数必须是类的成员函数,重载的函数则不一定是这样;
构造函数可以重载,但不能是虚函数,析构函数可以是虚函数。