[英]Virtual methods with multiple argument types in C++
Lets say I have a base class A that I want to have a method getName that can take in either an integer or a string as the argument. 可以说我有一个基类A,我想要一个方法getName可以接受整数或字符串作为参数。 So I create: 所以我创建:
virtual string getName(int index) = 0;
virtual string getName(string key) = 0;
Now, I want to create two different subclasses B and C. B only needs the getName(int index)
and C only needs the getName(string key)
. 现在,我想创建两个不同的子类B和C。B只需要getName(int index)
而C只需要getName(string key)
。 However, if I dont overwrite both methods in both subclasses, I get an error. 但是,如果我不覆盖两个子类中的两个方法,则会收到错误消息。 But if I do this, then B and C will have an empty methods because they dont need the other case of getName
但是,如果我这样做,那么B和C将有一个空方法,因为它们不需要getName
的另一种情况
How can I overcome this problem? 我该如何克服这个问题?
It sounds like you actually want two different interfaces: one that supports getName(int)
and one that supports getName(string)
. 听起来您实际上需要两个不同的接口:一个支持getName(int)
,另一个支持getName(string)
。
struct GetNameInt {
virtual string getName(int index) = 0;
};
struct GetNameStr {
virtual string getName(string key) = 0;
};
struct B : GetNameInt { /* ... */ };
struct C : GetNameStr { /* ... */ };
If you really need a single base class with the same interface, and you only know at run-time whether you'll need a string
or an int
, you might want to use std::variant
: 如果确实需要具有相同接口的单个基类,并且仅在运行时知道需要string
还是int
,则可能需要使用std::variant
:
struct GetName {
virtual string getName(std::variant<int, string>) = 0;
};
You're not using inheritance properly. 您没有正确使用继承。 I strongly recommend reading more about the SOLID principles . 我强烈建议您阅读有关SOLID原则的更多信息。
You need to split the class A into two classes (interfaces) - Aa and Ab, where Aa would hold getName(int index) and would have getName(string key), like: 您需要将类A分为两个类(接口)-Aa和Ab,其中Aa将保存getName(int索引)并具有getName(string键),例如:
class A {
//does not define neither of the getName methods
}
class Aa {
virtual string getName(int index) = 0;
}
class Ab {
virtual string getName(string key) = 0;
}
class B : A, Aa {
//inherits from A and defines string getName(int index)
}
class C : A, Ab {
//inherits from A and defines string getName(string key)
}
Ok, the best I can come up with to keep a common parent between B and C while still preserving some type safety and compile time check: 好的,我想出的最好的办法是在B和C之间保持一个公共父级,同时仍然保留一些类型安全性和编译时间检查:
struct CommonA //protect this if possible
{
template<class type>
string getGenericName(type index);
virtual ~CommonA() {}
};
template<class indexType>
struct A : CommonA
{
virtual string getName(indexType index) = 0;
};
struct B : A<int>
{
string getName(int index) override {cout << index << "\n"; }
};
struct C : A<string>
{
string getName(string index) override {cout << index << "\n"; }
};
template<class type>
string CommonA::getGenericName(type index)
{
cout << "generic call: \n";
return dynamic_cast<A<type>*>(this)->getName(index);
}
int main()
{
CommonA b = B();
CommonA c = C();
b.getGenericName(1);
c.getGenericName(string("hello world"));
}
Note that this solution is not a standard OOP solution but a template solution. 请注意,此解决方案不是标准的OOP解决方案,而是模板解决方案。
Edit: my templated A<> class is the same as Vittorio Romeo's solution using template instead of name pasting (name pasting is evil) 编辑:我的模板化A <>类与使用模板而不是名称粘贴的Vittorio Romeo的解决方案相同(名称粘贴是邪恶的)
By simply don't making them pure virtual, but just virtual: 通过简单地使它们不是纯虚拟的,而是纯虚拟的:
struct Blub
{
virtual void do1() {} // default definition
virtual void do2() = 0; //has to be overridden
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.