是否有一种方法可以强制在子类中实现方法,在该子类中,每个派生类的实现都有不同的签名?
我知道我可以使用纯虚拟机做到这一点:
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,然后确保每个派生类都实现其版本。
答案 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::variant
或std::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
中的虚拟分隔符。但这被认为是不好的设计。