C++ c+中的多级继承+;(CRTP)

C++ c+中的多级继承+;(CRTP),c++,crtp,C++,Crtp,请帮我解决这个问题WhiteDragon是调用Dragon::attacks()而不是 MonsterImplement::attacks(),此处存在歧义错误。如果我把龙换成 从MonsterImplement派生,然后行 std::cout numAttacks (摘自之前的评论。) 透视图#1 CRTP旨在提供非动态行为。如果“numAttacks”的值随每个派生类的不同而不同,则这不是“非动态”情况。一个反例是在派生类中放置一个非静态非虚拟方法int-numAttacks(){retur

请帮我解决这个问题
WhiteDragon
是调用
Dragon::attacks()
而不是
MonsterImplement::attacks()
,此处存在歧义错误。如果我把龙换成 从MonsterImplement派生,然后行
std::cout numAttacks
(摘自之前的评论。)

透视图#1 CRTP旨在提供非动态行为。如果“numAttacks”的值随每个派生类的不同而不同,则这不是“非动态”情况。一个反例是在派生类中放置一个非静态非虚拟方法
int-numAttacks(){return 3;}
,然后在CRTP基类中添加一些方法(在所有派生类中共享的攻击逻辑),然后可以在其派生类上调用
numAttacks()
方法,不会引起虚拟函数调用

例如:

struct Monster
{
    virtual void attack() = 0;
    virtual int getNumAttacks() const = 0;
};

template <struct MONSTER>
struct AttackLogic : virtual public Monster
{
    virtual void attack() override
    {
        /* allowed to call MONSTER::getNumAttacks(), renamed to avoid confusion. */

        int numAttacks = static_cast<MONSTER*>(this).getNumAttacks();

        /* Use the value in attack calculations. */
    }
};

struct Unicorn 
    : virtual public Monster
    , virtual public AttackLogic<Unicorn>
{
    virtual int getNumAttacks() const override
    {
        return 42; // Unicorn is awesome
    }
};

然后在
WhiteDragon
中提供一个具体的实现,返回3

struct WhiteDragon : ... 
{   ... 
    virtual int numAttacks() const override { return 3; } 
    ... 
};


(摘自之前的评论。)

透视图#1 CRTP旨在提供非动态行为。如果“numAttacks”的值随每个派生类的不同而不同,则这不是“非动态”情况。一个反例是在派生类中放置一个非静态非虚拟方法
int-numAttacks(){return 3;}
,然后在CRTP基类中添加一些方法(在所有派生类中共享的攻击逻辑),然后可以在其派生类上调用
numAttacks()
方法,不会引起虚拟函数调用

例如:

struct Monster
{
    virtual void attack() = 0;
    virtual int getNumAttacks() const = 0;
};

template <struct MONSTER>
struct AttackLogic : virtual public Monster
{
    virtual void attack() override
    {
        /* allowed to call MONSTER::getNumAttacks(), renamed to avoid confusion. */

        int numAttacks = static_cast<MONSTER*>(this).getNumAttacks();

        /* Use the value in attack calculations. */
    }
};

struct Unicorn 
    : virtual public Monster
    , virtual public AttackLogic<Unicorn>
{
    virtual int getNumAttacks() const override
    {
        return 42; // Unicorn is awesome
    }
};

然后在
WhiteDragon
中提供一个具体的实现,返回3

struct WhiteDragon : ... 
{   ... 
    virtual int numAttacks() const override { return 3; } 
    ... 
};


(摘自之前的评论。)

透视图#1 CRTP旨在提供非动态行为。如果“numAttacks”的值随每个派生类的不同而不同,则这不是“非动态”情况。一个反例是在派生类中放置一个非静态非虚拟方法
int-numAttacks(){return 3;}
,然后在CRTP基类中添加一些方法(在所有派生类中共享的攻击逻辑),然后可以在其派生类上调用
numAttacks()
方法,不会引起虚拟函数调用

例如:

struct Monster
{
    virtual void attack() = 0;
    virtual int getNumAttacks() const = 0;
};

template <struct MONSTER>
struct AttackLogic : virtual public Monster
{
    virtual void attack() override
    {
        /* allowed to call MONSTER::getNumAttacks(), renamed to avoid confusion. */

        int numAttacks = static_cast<MONSTER*>(this).getNumAttacks();

        /* Use the value in attack calculations. */
    }
};

struct Unicorn 
    : virtual public Monster
    , virtual public AttackLogic<Unicorn>
{
    virtual int getNumAttacks() const override
    {
        return 42; // Unicorn is awesome
    }
};

然后在
WhiteDragon
中提供一个具体的实现,返回3

struct WhiteDragon : ... 
{   ... 
    virtual int numAttacks() const override { return 3; } 
    ... 
};


(摘自之前的评论。)

透视图#1 CRTP旨在提供非动态行为。如果“numAttacks”的值随每个派生类的不同而不同,则这不是“非动态”情况。一个反例是在派生类中放置一个非静态非虚拟方法
int-numAttacks(){return 3;}
,然后在CRTP基类中添加一些方法(在所有派生类中共享的攻击逻辑),然后可以在其派生类上调用
numAttacks()
方法,不会引起虚拟函数调用

例如:

struct Monster
{
    virtual void attack() = 0;
    virtual int getNumAttacks() const = 0;
};

template <struct MONSTER>
struct AttackLogic : virtual public Monster
{
    virtual void attack() override
    {
        /* allowed to call MONSTER::getNumAttacks(), renamed to avoid confusion. */

        int numAttacks = static_cast<MONSTER*>(this).getNumAttacks();

        /* Use the value in attack calculations. */
    }
};

struct Unicorn 
    : virtual public Monster
    , virtual public AttackLogic<Unicorn>
{
    virtual int getNumAttacks() const override
    {
        return 42; // Unicorn is awesome
    }
};

然后在
WhiteDragon
中提供一个具体的实现,返回3

struct WhiteDragon : ... 
{   ... 
    virtual int numAttacks() const override { return 3; } 
    ... 
};

模板
结构怪物int:虚拟公共怪物{
静态int-numAttacks;
};
这门课的目的是什么?看起来它所做的只是给一个类一些攻击,在这种情况下,从怪物中派生出来是没有意义的

template <int NUM>
struct MonsterInt {
    static int numAttacks;
   };
模板
结构怪物智力{
静态int-numAttacks;
};
我认为,这“修复”了程序,但很难说清楚,因为很难从代码中派生出意图。

template
结构怪物int:虚拟公共怪物{
静态int-numAttacks;
};
这门课的目的是什么?看起来它所做的只是给一个类一些攻击,在这种情况下,从怪物中派生出来是没有意义的

template <int NUM>
struct MonsterInt {
    static int numAttacks;
   };
模板
结构怪物智力{
静态int-numAttacks;
};
我认为,这“修复”了程序,但很难说清楚,因为很难从代码中派生出意图。

template
结构怪物int:虚拟公共怪物{
静态int-numAttacks;
};
这门课的目的是什么?看起来它所做的只是给一个类一些攻击,在这种情况下,从怪物中派生出来是没有意义的

template <int NUM>
struct MonsterInt {
    static int numAttacks;
   };
模板
结构怪物智力{
静态int-numAttacks;
};
我认为,这“修复”了程序,但很难说清楚,因为很难从代码中派生出意图。

template
结构怪物int:虚拟公共怪物{
静态int-numAttacks;
};
这门课的目的是什么?看起来它所做的只是给一个类一些攻击,在这种情况下,从怪物中派生出来是没有意义的

template <int NUM>
struct MonsterInt {
    static int numAttacks;
   };
模板
结构怪物智力{
静态int-numAttacks;
};

我认为这“修复”了程序,但很难说真话,因为很难从代码中获得意图。

我不明白为什么这里到处都有模板。似乎您试图通过它实现的大多数事情都可以通过简单的多态性来完成。但也许我错了。我的整个代码都有许多静态数据成员,所以我想使用模板(和多重继承)为所有Monster子类型建立静态数据成员(numAttacks就是这样一个,如上所示)。我可以简化上面的内容,以获得我想要在这里实现的目标,但这样做的代价是所有相同的怪物将拥有不再是静态的公共值。这里的问题是CRTP不是单级的。@Aruistante,也许你从未见过。我对这个例子的研究还不够深入,不知道它在这里的使用是否正确。我的意思是,您完全可以共享静态数据成员(这就是类中的
static
关键字的全部要点)。CRTP似乎主要用于避免虚拟函数表查找的性能损失