2

简单地说,我需要按照标题说的做:从父级调用子级静态方法。问题是我不知道父类中的子类名称,因为可能有多个子类。静态方法需要保持静态。例如:

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();
}

有什么建议么?

谢谢!

4

3 回答 3

3

你可以使用模板。

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;
于 2013-08-11T22:27:27.317 回答
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) {}
    // ...
};

这是一种按对象可覆盖的虚函数的实现。

于 2013-08-11T22:25:08.873 回答
1

您可以在静态函数周围使用虚拟包装器。例如

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(); }
}
于 2013-08-11T22:29:17.187 回答