Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Can';派生类的t调用方法-编译器将对象实例标识为基类_C++_Inheritance_Methods_Compiler Errors_Base Class - Fatal编程技术网

C++ Can';派生类的t调用方法-编译器将对象实例标识为基类

C++ Can';派生类的t调用方法-编译器将对象实例标识为基类,c++,inheritance,methods,compiler-errors,base-class,C++,Inheritance,Methods,Compiler Errors,Base Class,调用派生类中定义的方法时出现编译器错误。编译器似乎认为我所指的对象属于基类类型: weapon = dynamic_cast<Weapon*>(WeaponBuilder(KNIFE) .name("Thief's Dagger") .description("Knife favored by Thieves") .attack(7) // error: class Builder has no member called attack .cost(10) // er

调用派生类中定义的方法时出现编译器错误。编译器似乎认为我所指的对象属于基类类型:

weapon = dynamic_cast<Weapon*>(WeaponBuilder(KNIFE)
.name("Thief's Dagger")
.description("Knife favored by Thieves")
.attack(7)    // error: class Builder has no member called attack 
.cost(10)     // error: class Builder has no member called cost
.build());
但是派生类
WeaponBuilder
可以:

enum WeaponType { NONE, KNIFE, SWORD, AXE, WAND };

class WeaponBuilder : public Builder
{
    int m_cost;
    int m_attack;
    int m_magic;

    WeaponType m_type;

public:

    WeaponBuilder();
    WeaponBuilder(WeaponType);
    ~WeaponBuilder();

    GameComponent* build() const;

    // should these be of reference type Builder or WeaponBuilder?
    WeaponBuilder& cost(int); 
    WeaponBuilder& attack(int);
    WeaponBuilder& magic(int);

};

我不知道为什么编译器在
WeaponBuilder
类中找不到
attack
cost
方法,因为它显然存在。我也不清楚为什么它会将对象识别为基类
Builder

的实例,因为
name
description
都返回一个
Builder&
而不是
WeaponBuilder&
,因此没有其他方法。除了到处强制转换之外,您的代码没有明确的解决方案

您可以使用CRTP重写整个过程并解决您的问题,但这是一个重大的变化。以下几行中的某一行:

template< typename Derived >
class builder
{
    Derived& name( std::string const& name ){ /*store name*/, return *derived(); }

    Derived* derived(){ return static_cast< Derived* >( this ); }
};

class weapon_builder : builder< weapon_builder >
{
    weapon_builder& attack( int ){ /*store attack*/ return *this; }

    GameComponent* build() const{ return something; }
};
模板
类生成器
{
派生名称(std::string const&name){/*存储名称*/,返回*派生();}
派生*派生(){return static_cast(this);}
};
类武器构建器:构建器<武器构建器>
{
武器构建与攻击(int){/*存储攻击*/返回*此;}
GameComponent*build()常量{return something;}
};

请注意,使用这种方法,所有的
虚拟方法都应该消失,并且您将失去引用普通
构建器的能力,因为它不再是一个常见的基类型,而是一个类模板。

您的意图可能是这样的:

weapon = dynamic_cast<Weapon*>(dynamic_cast<WeaponBuilder &>(WeaponBuilder(KNIFE)
.name("Thief's Dagger")
.description("Knife favored by Thieves"))
.attack(7)    
.cost(10)     
.build());
武器=动态施法(动态施法)(武器制造者(刀) .name(“小偷的匕首”) .描述(“小偷喜欢的刀”)) .攻击(7) .费用(10) .build());
我看到了问题所在,因为我在调用
name
description
的方法后返回了对Builder的引用。Drats.此模式是否适用于继承
Builder
类的多个对象?我的想法是为游戏中的每个复杂对象使用一个
Builder
。@Dylan:是的,它可以工作,你可以使用这个模式创建不同的构建器,所有的构建器共享同一个隐式界面。但是请注意,除了隐式接口之外,这些类型之间没有任何共同之处,它们在其他方面是完全不相关的类型。我实现了上述功能,但在main中创建武器生成器对象时,当我调用模板类中定义的
name
description
的成员时,我得到了一个“找不到符号”错误。@Dylan:哦,是的,是的,模板方法必须在头文件中定义。这消除了调用
攻击
方法时的错误,但对我来说仍然会导致编译器错误,代价是
成本
weapon = dynamic_cast<Weapon*>(dynamic_cast<WeaponBuilder &>(WeaponBuilder(KNIFE)
.name("Thief's Dagger")
.description("Knife favored by Thieves"))
.attack(7)    
.cost(10)     
.build());