我有一个抽象基类IThingDoer
,带有一个虚拟
方法doThingWithData
。我想要的是让 IThingDoer
的具体类实现 doThingWithData(&someType dat)
,除了 dat
的变量类型(即什么 someType
是)在不同的具体类之间变化。
例如:
class IThingDoer {
public:
virtual void doThingWithData(&someType dat); //??
};
struct Foo {
int foo1;
double foo2;
};
class FooThingDoer : public IThingDoer {
public:
void doThingWithData(&Foo dat){
std::cout << dat.foo1
}
};
struct Bar {
float bar1[2];
};
class BarThingDoer : public IThingDoer {
public:
void doThingWithData(&Bar dat){
std::cout << (dat.bar1[0] + dat.bar1[1]);
}
};
我试过让 Foo
和 Bar
都继承自另一个基数据类:(我改变了实际发生的情况以稍微简化示例)
class BaseData{
public:
int baseData = 1;
};
class IThingDoer{
public:
virtual void doThingWithData(BaseData dat) = 0;
};
class FooData : public BaseData {
public:
int otherData = 5;
};
class FooThingDoer : public IThingDoer {
public:
void doThingWithData(BaseData dat){
std::cout << dat.otherData;
}
};
int main()
{
FooThingDoer a = FooThingDoer();
FooData dat = FooData();
a.doThingWithData(dat);
return 0;
}
但是,这不起作用 - 编译器找不到 dat.otherData
,因为 BaseData
类型中没有 otherData
.在 FooThingDoer.doThingWithData
中将 BaseData
更改为 FooData
也不起作用,因为这只会导致它重载名称而不是实际实现虚拟IThingDoer
中的函数。
我也查看了模板,但是(从一个相对缺乏经验的程序员的角度来看)看起来模板主要用于减少为每种不同的可能类型重载函数的需要。
需要说明的是,未知数据类型只是抽象类不知道的;它们将在编译时已知。
有没有办法解决这个问题?
附录:我可能正在处理 XY 问题;出于这个原因,我在这里添加了一些额外的上下文。
从更大的角度来看,这段代码将在不同的硬件上运行,具有不同的传感器和它需要控制的东西。不同的 ThingDoer 实现了需要发生的特定功能,但在所有情况下,每个 ThingDoer 都可以被视为一个黑盒子,它将一些数据结构作为输入,并执行一些 Action 作为输出,具体的输入数据结构在不同的 ThingDoers 之间变化.
据我了解,为了提高程序其余部分的代码重用等,每个 ThingDoer 都应继承一个描述此黑盒功能的抽象类,其余代码应使用此接口(interface)。我计划让单独的对象准备 ThingDoer 作为输入的实际数据结构;同样,我会为每种硬件类型提供一个准备器对象。
然后,根据我正在编译的硬件,我会在编译中包含不同的头文件(包含我需要的特定 ThingDoer 等)。由于在编译时有一个特定的 ThingDoer 和相应的输入准备器被使用,我认为这些类型在编译时是已知的,所以没有任何动态类型。
最佳答案
静态多态可以使用模板。
#include <iostream>
template <class T>
class IThingDoer {
public:
virtual void doThingWithData(T dat) = 0;
};
struct Foo {
int foo1;
double foo2;
};
class FooThingDoer : public IThingDoer<Foo> {
public:
void doThingWithData(Foo dat) {
std::cout << dat.foo1;
}
};
struct Bar {
float bar1[2];
};
class BarThingDoer : public IThingDoer<Bar> {
public:
void doThingWithData(Bar dat) {
std::cout << (dat.bar1[0] + dat.bar1[1]);
}
};
int main()
{
FooThingDoer a = FooThingDoer();
Foo foo;
foo.foo1 = 5;
foo.foo2 = 5.5;
a.doThingWithData(foo);
return 0;
}
但是你的例子也可以使用(你只能转换地址,而不是静态对象):
#include <iostream>
class BaseData {
public:
int baseData = 1;
};
class IThingDoer {
public:
virtual void doThingWithData(BaseData& dat) = 0;
};
class FooData : public BaseData {
public:
int otherData = 5;
};
class FooThingDoer : public IThingDoer {
public:
void doThingWithData(BaseData& dat) {
std::cout << ((FooData&) dat).otherData;
}
};
int main()
{
FooThingDoer a = FooThingDoer();
FooData dat = FooData();
a.doThingWithData(dat);
return 0;
}
关于c++ - 在抽象基类定义中使用未知类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58706237/