考虑以下抽象类AbstractEngine
:
class AbstractEngine {
static void init();
static std::string getName();
};
考虑以下2个实现者类:
class Engine1 : public AbstractEngine {
static std::string getName();
};
class Engine2 : public AbstractEngine {
static std::string getName();
};
而且,init()
函数应该根据类的类型调用正确的getName()
:
void AbstractEngine::init() {
std::cout << getName() << std::endl;
}
例如,如果我致电Engine1::init()
,我希望致电Engine1::getName()
而不是AbstractEngine::getName()
如何让AbstractEngine::init()
真正调用getName()
的正确实现?
答案 0 :(得分:11)
您可以使用CRTP,即使AbstractEngine
成为模板类,然后在继承时继承AbstractEngine<EngineN>
:
template <typename T>
class AbstractEngine {
public:
static void init() {
std::cout << T::getName() << std::endl;
}
};
class Engine1 : public AbstractEngine<Engine1> {
public:
static std::string getName() { return "Engine1"; }
};
class Engine2 : public AbstractEngine<Engine2> {
public:
static std::string getName() { return "Engine2"; }
};
如果您还需要一些动态多态行为,则可以创建一个通用的非模板基类:
class AbstractEngine {
//I assume you would have some virtual functions here
};
template <typename T>
class AbstractEngineImpl : public AbstractEngine {
public:
static void init() {
std::cout << T::getName() << std::endl;
}
};
class Engine1 : public AbstractEngineImpl<Engine1> {
public:
static std::string getName() { return "Engine1"; }
};
class Engine2 : public AbstractEngineImpl<Engine2> {
public:
static std::string getName() { return "Engine2"; }
};
答案 1 :(得分:1)
getName()
方法不应该是静态的。不是init()
方法。
答案 2 :(得分:1)
你试图获得多态行为,但是使用静态函数。这没有任何意义。根据定义,多态行为与特定的对象实例相关联 - 但静态函数没有关联的实例。
如果您想要多态行为(如标记所示),请考虑重新设计:
class AbstractEngine {
virtual void init();
virtual std::string getName();
};
class Engine1 : public AbstractEngine {
std::string getName() override;
};
class Engine2 : public AbstractEngine {
std::string getName() override;
};