C ++:从父级调用子静态方法

时间:2013-08-11 22:11:37

标签: c++ inheritance static

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

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

有什么建议吗?

谢谢!

3 个答案:

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