1

我正在尝试创建一个同时代表两种不同行为的类。如下所示:

class IMouse {
public:
    virtual void Walk() const = 0;
};

class TSimpleMouse : public IMouse {
public:
    void Walk() const;
};

class IBat {
public:
    virtual void Fly() const = 0;
};

class TSimpleBat : public IBat {
public:
    void Fly() const;
};

template <class TMouse, class TBat>
class TSuperCreatureImpl {
public:
    void Do() const {
        Walk();
        Fly();
    }
};

typedef TSuperCreatureImpl<TSimpleMouse, TSimpleBat> TSimpleSuperCreature;

这对我来说很重要,因为我想做不同的 typedefs。这似乎很简单。

但我也希望 Fly 和 Walk 方法具有参数(例如速度)。我应该如何修改架构以便有机会为不同的生物使用许多 typedef?

如果没有 Mouse 和 Bat 的默认构造函数,如何更改架构?

非常感谢。

4

3 回答 3

3
template <class TMouse, class TBat>
class TSuperCreature : public TMouse, public TBat
{
  public:
    void do() const {
        this->walk();
        this->fly();
    }
};

但我也希望 Fly 和 Walk 方法具有参数(例如速度)。我应该如何修改架构以便有机会为不同的生物使用许多 typedef?非常感谢。

您可以为函数提供默认参数...

virtual void Walk(double meters_per_second = 1.1) const = 0;

编辑

(来自下面的评论)假设我们需要 2 个生物:第一个走得快,飞得慢,第二个正好相反。这意味着我们必须编写 2 个 typedef。但我不知道如何在这里使用速度常数。架构的哪些部分必须有参数?

一种选择是执行以下操作:

template <class TMouse, class TBat, int walk_speed, int fly_speed>
class TSuperCreature : public TMouse, public TBat
{
  public:
    void do() const {
        this->walk(walk_speed);
        this->fly(fly_speed);
    }
};

如果您想使用doubles,则不允许它们作为模板参数(至少在 C++03 中不允许),但作为一种技巧,您可以接受一对数字并将它们划分在模板中,或者更准确地说,您可以提供政策课……

template <class TMouse, class TBat, class Speeds>
class TSuperCreature : public TMouse, public TBat
{
  public:
    void do() const {
        this->walk(Speeds::walk_speed);
        this->fly(Speeds::fly_speed);
    }
};

struct Speeds__Fly_Fast__Walk_Slow   // yes I know double underscores are reserved - I don't care!
{
    static const double walk_speed = 0.5; // m/s
    static const double fly_speed = 10;
};
于 2012-06-08T15:48:34.770 回答
1

为什么不简化。

有一个以移动方法为参数的移动接口;

enum MovementMethod { Walk, Fly, Swim };

class MoveInterface
{
    public:
        virtual void move(MovementMethod method) = 0;
};
// TMouse/TBat inheret from the MoveInterface

template <class TMouse, class TBat>
class TSuperCreatureImpl : public TMouse, public TBat
{
    public:
        virtual void move(MovementMethod /*method*/) 
        {
            TMouse::move(Walk);
            TBat::move(Fly);
        }
};
于 2012-06-08T15:51:34.590 回答
0

如果您一次只需要一种特殊行为,我会应用策略模式。然后,您的 Do-Method 可以调用当前策略,即 walk 或 fly。您可以拥有一个 CurrentBehaviour,在需要时选择它。

此外,我会想到一个装饰器,在需要时简单地添加所需的行为。即,当您需要超级生物时,您有一系列行为并添加鼠标和蝙蝠。当需要一个也可以吠叫的超级生物时,只需添加一个狗行为。

于 2012-06-08T15:54:05.533 回答