#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) 若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类的构造函数。
重载函数在类型和参数数量上一定不相同,而重定义的虚函数则要求参数的类型和个数、函数返回类型相同;
虚函数必须是类的成员函数,重载的函数则不一定是这样;
构造函数可以重载,但不能是虚函数,析构函数可以是虚函数。