C++从多重继承的模板类中调用虚拟方法
C++ Calling a virtual method from a multiply inherited template class
我这里有很多代码,但恐怕这是我能表达问题的最少量代码,所以请耐心等待:
#include <iostream>
#define ASINSTANCE(x, type, y)
type * y = dynamic_cast<type *>(&(x));
if (y)
class Fruit {
virtual void a() = 0; // This is to surpress the "Fruit isn't polymorphic" we'd otherwise get.
};
class Apple : public Fruit {
virtual void a() {
}
};
class Orange : public Fruit {
virtual void a() {
}
};
class Banana : public Fruit {
virtual void a() {
}
};
template<typename FruitType>
class FruitEater {
protected:
virtual void eat(const FruitType & t) = 0;
};
template<typename... FruitTypes>
class MultiFruitEater : public FruitEater<FruitTypes>... {
public:
// Eat any fruit if it belongs to FruitTypes (returns false otherwise).
bool dispatchEat(const Fruit & fruit);
private:
template<typename First>
bool dispatchEatByType(const Fruit & fruit);
template<typename First, typename Second, typename... Rest>
bool dispatchEatByType(const Fruit & fruit);
};
class MyEater : public MultiFruitEater<Apple, Orange, Banana> {
protected:
virtual void eat(const Apple & t);
virtual void eat(const Orange & t);
virtual void eat(const Banana & t);
};
void MyEater::eat(const Apple & t) {
std::cout << "Ate apple." << std::endl;
}
void MyEater::eat(const Orange & t) {
std::cout << "Ate orange." << std::endl;
}
void MyEater::eat(const Banana & t) {
std::cout << "Ate banana." << std::endl;
}
template<typename... FruitTypes>
bool MultiFruitEater<FruitTypes...>::dispatchEat(const Fruit & fruit) {
return dispatchEatByType<FruitTypes...>(fruit);
}
template<typename... FruitTypes>
template<typename First>
bool MultiFruitEater<FruitTypes...>::dispatchEatByType(const Fruit & fruit) {
ASINSTANCE(fruit, const First, pCastFruit) {
eat(*pCastFruit);
return true;
}
return false;
}
template<typename... FruitTypes>
template<typename First, typename Second, typename... Rest>
bool MultiFruitEater<FruitTypes...>::dispatchEatByType(const Fruit & fruit) {
ASINSTANCE(fruit, const First, pCastFruit) {
eat(*pCastFruit);
return true;
}
return dispatchEatByType<Second, Rest...>(fruit);
}
int main() {
MyEater eater;
Banana b;
eater.dispatchEat(b);
}
问题出在线路上:
eat(*pCastFruit);
我得到以下错误:
- 错误C2385:对"eat"的访问不明确
- 错误C3861:"eat":找不到标识符
我试着用替换这条线
this->FruitEater<First>::eat(*pCastFruit);
错误现在更改为:
错误LNK2019:未解析的外部符号"protected:virtualvoid __thiscall FruitEater::eat(class Apple const&)"(?吃@$FruitEater@VApple@@@@MAEXABVApple@@@Z)"private:boll__thiscall MultiFruitEater::dispatchEatByType(class Fruit const&)"($dispatchEatByType@VApple@@VOrange@@VBanana@@@$MultiFruitEater@VApple@@VOrange@@VBanana@@@@AAE_NABVFruit@@@Z)
错误LNK2019:未解析的外部符号"protected:virtualvoid __thiscall FruitEater::eat(class Banana const&)"(?吃@$FruitEater@VBanana@@@@MAEXABVBanana@@@Z)函数"private:boll__thiscall MultiFruitEater::dispatchEatByType(类Fruitconst&)"($dispatchEatByType@VBanana@@@$MultiFruitEater@VApple@@VOrange@@VBanana@@@@AAE_NABVFruit@@@Z)
有什么想法吗?
分辨率:
所以我得到了你的回复:
使用您定义的ASSISTANCE:(因为您现在发送的类型不是常量
#define ASINSTANCE(x, type, y, eater)
const type * y = dynamic_cast<const type *>(&(x));
FruitEater<type>* eater = dynamic_cast<FruitEater< type >*>(this);
if (y && eater)
在你的水果食客课上:(它让你的多食客学会了的饮食方法
template<typename FruitType>
class FruitEater {
protected:
template<typename... Fruit> friend class MultiFruitEater;
virtual void eat(const FruitType & t) = 0;
};
如何使用您的新助理定义:
ASINSTANCE(fruit, First, pCastFruit, eater) {
eater->eat(*pCastFruit);
return true;
}
解释:(没有我想要的那么精确)
我认为这样做(this->FruitEater<First>::eat(*pCastFruit);
)的问题是,你强迫编译器使用FruitEater::eat()方法,这是一个虚拟的void。。。
- 是否可以使用函数指针调用虚拟析构函数?
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 使用在堆栈上创建的对象调用虚拟函数
- 如何从派生类函数中调用虚拟函数
- 从内部类的析构函数调用虚拟函数
- 使用范围解析运算符时,在构造函数中调用虚拟方法是否安全?
- 调用虚拟成员类的方法
- 为什么不调用虚拟基非默认构造函数,除非大多数派生基显式调用它们?
- 为什么在运行时调用虚拟函数时需要虚拟表
- 从C++中的虚拟析构函数调用虚拟方法
- 如何在C++中调用虚拟析构函数
- 调用虚拟函数而不通过类类型指针创建任何对象
- 通过命名成员调用虚拟与地址或引用的区别
- 从派生的指针中调用虚拟功能,而无需支付VTable价格
- 为什么我不能从铸造的字节(char)数组中调用虚拟函数
- 在基类崩溃中调用虚拟功能
- 可以通过跨二进制边界传递的对象上的接口调用虚拟函数吗?
- 调用虚拟方法的不同方法
- C++未根据需要调用虚拟方法