关于c++ class中virtual 函数的几种替代方案
2016-10-17 11:33
253 查看
1 NVI (Non-Virtual Interface)
看下面的类继承关系:
class GameCharactor
{
public:
virtual void CalculateScore(const GameCharactor& charactor);
};
class ACharactor : public GameCharactor
{
public:
virtual void CalculateScore(const GameCharactor& charactor);
};
class BCharactor : public GameCharactor
{
virtual void CalculateScore(const GameCharactor& charactor);
};
我们用基类来抽象游戏中的一个角色,这个角色有一个计算自身得分的函数CalculateScore(),由于继承自此基类的每一个子类很可能都有他们自己的计算得分的方法,所以我们在设计的时候首先想到,将这个计算得分的函数定义为虚函数,子类继承并重写之。但是这样就存在两个问题,其一是可扩展性不高,假设每个子类在调用得分函数之前、之后需要做一些各自的其他操作呢,所以将基类改为如下设计,用Non-Virtual的函数取代Virtual函数作为提供给用户的借口:
class GameCharactor
{
public:
void GetScore(){ CalculateScore(*this); }
private:
virtual void CalculateScore(const GameCharactor& charactor);
};
第二个问题是如果同一个子类的不同对象需要不同的计算得分的函数呢?所以在此引入第二种方案:
2、在参数中引入函数指针
typedef void (*GetScore)(cosnt GameCharactor&) ;
void DefaultSocre(const GameCharactor& charactor){..........}
class GameCharactor
{
public:
GameCharactor(GetSocre getscore = DefaultSocre):GetCharactorScore(getscore ){}
void GetScore(){ GetCharactorScore(*this);}
private:
GetSocre GetCharactorScore;
};
这里通过传入函数指针的形式,可实现更细粒度的多态,并且还有一个好处就是可以动态改变每一个对象实例的计算得分的函数,比如可以通过SetScoreFunction()借口来实现。
3、上面第二种参数也可以通过传入对象指针的方式来实现,UML图如下:
总结:
虚函数可以用来实现继承于同一基类的不通子类之间的多态,通过引入指针或对象指针的方式可以实现更细粒度的多态,即同一子类不同对象之间的多态。上述三种方式中的后两种方式是strategy设计模式的应用。
看下面的类继承关系:
class GameCharactor
{
public:
virtual void CalculateScore(const GameCharactor& charactor);
};
class ACharactor : public GameCharactor
{
public:
virtual void CalculateScore(const GameCharactor& charactor);
};
class BCharactor : public GameCharactor
{
virtual void CalculateScore(const GameCharactor& charactor);
};
我们用基类来抽象游戏中的一个角色,这个角色有一个计算自身得分的函数CalculateScore(),由于继承自此基类的每一个子类很可能都有他们自己的计算得分的方法,所以我们在设计的时候首先想到,将这个计算得分的函数定义为虚函数,子类继承并重写之。但是这样就存在两个问题,其一是可扩展性不高,假设每个子类在调用得分函数之前、之后需要做一些各自的其他操作呢,所以将基类改为如下设计,用Non-Virtual的函数取代Virtual函数作为提供给用户的借口:
class GameCharactor
{
public:
void GetScore(){ CalculateScore(*this); }
private:
virtual void CalculateScore(const GameCharactor& charactor);
};
第二个问题是如果同一个子类的不同对象需要不同的计算得分的函数呢?所以在此引入第二种方案:
2、在参数中引入函数指针
typedef void (*GetScore)(cosnt GameCharactor&) ;
void DefaultSocre(const GameCharactor& charactor){..........}
class GameCharactor
{
public:
GameCharactor(GetSocre getscore = DefaultSocre):GetCharactorScore(getscore ){}
void GetScore(){ GetCharactorScore(*this);}
private:
GetSocre GetCharactorScore;
};
这里通过传入函数指针的形式,可实现更细粒度的多态,并且还有一个好处就是可以动态改变每一个对象实例的计算得分的函数,比如可以通过SetScoreFunction()借口来实现。
3、上面第二种参数也可以通过传入对象指针的方式来实现,UML图如下:
总结:
虚函数可以用来实现继承于同一基类的不通子类之间的多态,通过引入指针或对象指针的方式可以实现更细粒度的多态,即同一子类不同对象之间的多态。上述三种方式中的后两种方式是strategy设计模式的应用。
相关文章推荐
- c++中关于数组作为函数参数并传递数组元素个数的几种有效方法的讨论
- 关于c++中模板 T 无法限制的替代方案template< T extends Base>
- [C++] 关于virtual 函数
- c++中关于数组作为函数参数并传递数组元素个数的几种有效方法的讨论
- 条款35 考虑virtual函数以外的其他选择(virtual函数的替代方案)
- c++中关于数组作为函数参数并传递数组元素个数的几种有效方法的讨论
- c++中关于数组作为函数参数的几种方法
- 关于c++ const 函数参数
- 一小段C++程序,关于ltoa函数的
- C++ 内存布局(二) 虚继承 ---Empty virtual base classs (空虚基类)
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 转:关于在C++内用指针调用类的成员函数
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 关于C++的一些细节[五:函数-基础]
- C++笔试题 关于函数析构函数未调用的问题
- [C++]virtual关键字:虚函数,虚继承和虚基类
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 关于解决ASP环境下防止同一用户重复登录的问题的几种方案(20060110原创)
- 关于C++中函数指针的使用(包含对typedef用法的讨论)
- 关于classview中类的消失----几种解决方法