C ++强制在子类中实现方法,但签名不同

时间:2018-08-23 16:33:29

标签: c++ abstract-class

是否有一种方法可以强制在子类中实现方法,在该子类中,每个派生类的实现都有不同的签名?

我知道我可以使用纯虚拟机做到这一点:

class Base {
  public:
   virtual void getValue(string& s) = 0;
}

class Derived : public Base {
  public:
   void getValue(string& s);
}

以上,基类中的纯虚拟getValue强制派生类实现getValue。但是我真正想做的是这样的:强制每个派生类实现getValue(),但是每个都有不同的签名:

class Base {
  public:
   void getValue() = 0;
}

class Derived_A : public Base {
  public:
   void getValue(string& s);
}

class Derived_B : public Base {
  public:
   void getValue(int *j);
}

上述问题是,由于名称处理,每个签名实际上是一个不同的函数,因此Derived_A和Derived_B继承了getValue()= 0,并且编译器认为它们也是抽象的。

我一直在尝试一些不同的方法来执行此操作,但在我看来没有办法。我想我应该只在基类中 not 声明getValue,然后确保每个派生类都实现其版本。

2 个答案:

答案 0 :(得分:4)

如果可以使用CRTP,则可以使用:

#include <string>

template <typename TypeSelector>
class Base {
  public:
     using type = typename TypeSelector::type;
     virtual void getValue(type t) = 0;
};

struct TypeSelector_A {
   using type = std::string&;
};

class Derived_A : public Base<TypeSelector_A> {
   public:
      void getValue(std::string& s) { /* Add real implementation */ }
};

struct TypeSelector_B {
   using type = int*;
};

class Derived_B : public Base<TypeSelector_B> {
   public:
      void getValue(int* j) { /* Add real implementation */ }
};

int main()
{
   Derived_A a;
   Derived_A b;
}

答案 1 :(得分:1)

  

但是我真正想做的是这样的:强制每个派生类实现getValue(),但是每个都有不同的签名

具有虚函数(是否抽象)的全部要点是,可以将其与指针或对基类的引用一起使用,这意味着您将使用基类中函数的签名。有了那个,你想要的东西是完全没有用的。可以通过在树中的每个虚拟函数中返回std::variantstd::any来实现所需的内容,从而使签名保持不变。

您应该考虑,如果可能的话,将如何使用这种概念。如果您这样想:

void foo( Base *b ) {
    if( auto *d = dynamic_cast<Derived_A *>( b ) ) {
       std::string str;
       d->getValue( str );
       ...
    }
    if( auto *d = dynamic_cast<Derived_B *>( b ) ) {
       int i = 0;
       d->getValue( &i );
       ...
    }
}

然后getValue()不需要是虚拟的,您只需要Base中的虚拟分隔符。但这被认为是不好的设计。