简单地说,我需要按标题说明:从父级调用子静态方法。问题是我不知道父母中的子类名,因为可能有多个孩子。静态方法需要保持静态。例如:
class A{ // parent class
public:
void process(){
getData(); // <-- Problem
}
}
class B: public A{ // child class
static int getData();
}
void main(){
B b;
b.process();
}
我想到的一个解决方案是使用一个调用静态方法的虚方法。这不会很好,这意味着我必须为每个孩子实施该方法:
class A{ // parent class
virtual int getDataFromStaticMethod() = 0;
public:
void process(){
getData(); // <-- Problem
}
}
class B: public A{ // child class
static int getData();
virtual int getDataFromStaticMethod(){
return B::getData();
}
}
void main(){
B b;
b.process();
}
但我真的希望用静态方法实现纯虚方法:
class A{ // parent class
virtual int getData() = 0;
public:
void process(){
getData(); // <-- Problem
}
}
class B: public A{ // child class
static int getData();
}
void main(){
B b;
b.process();
}
有什么建议吗?
谢谢!
答案 0 :(得分:2)
您可以使用模板。
template<typename TChild>
class A
{
typedef TChild child_type;
public:
void process()
{
child_type::getData();
}
};
class B: public A<B>
{
static int getData();
};
class C: public A<C>
{
static int getData();
};
int main(int argc, char** argv)
{
B b;
b.process();
C c;
c.process();
}
注意:
如果要在基类中保持静态,或者如果需要保存基类对象的集合,则需要一个额外的层:
class ABase
{
//any static state goes here
public:
virtual int process() = 0;
};
template<typename TChild>
class A: public ABase
{
typedef TChild child_type;
public:
int process()
{
child_type::getData();
}
};
class B: public A<B>
{};
std::vector<ABase*> a_list;
答案 1 :(得分:1)
假设子函数的签名都是相同的,您可以初始化基类对象以保存指向孩子getData()
函数版本的指针,例如:
class A {
int (*d_getData)();
protected:
explicit A(int (*getData)()): d_getData(getData) {}
public:
void process() {
int data = (this->d_getData)();
// ...
}
};
显然,子类需要提供相应的构造函数参数:
class B: public A {
static int whatever();
public:
B(): A(&whatever) {}
// ...
};
这是每个对象可覆盖的虚函数的实现。
答案 2 :(得分:1)
您可以在静态函数周围使用虚拟包装器。 E.g。
class A{ // parent class
// don't make pure virtual if you don't want to define it in all child classes
virtual int getData() { return 0 };
public:
void process(){
getData();
}
}
class B: public a{ // child class
static int do_getData();
int getData() { return do_getData(); }
}