我有一个抽象基类IThingDoer
和一个virtual
方法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
,因为otherData
类型中没有BaseData
。在BaseData
中将FooData
更改为FooThingDoer.doThingWithData
也不起作用,因为这只会导致其重载名称,而实际上并未在IThingDoer
中实现虚函数。
我也看过模板,但是(从一个相对缺乏经验的程序员的角度来看),看起来模板似乎主要用于减少对每种可能类型的重载函数的需求。
需要明确的是,未知数据类型仅是抽象类所未知;它们将在编译时被知道。
有没有办法解决这个问题?
附录:我可能正在处理XY问题;因此,我在这里添加了一些其他上下文。
从更大的角度看,此代码将在不同的硬件上运行,具有不同的传感器和需要控制的东西。不同的ThingDoer实现了需要发生的特定功能,但是在所有情况下,每个ThingDoer都可以被视为黑匣子,该黑匣子将某些数据结构作为输入,并执行一些操作作为输出,并且特定的输入数据结构在不同的ThingDoers之间变化
据我了解,为了提高程序其余部分的代码重用性,每个ThingDoer应该从描述此黑匣子功能的抽象类继承,其余代码应与此接口一起工作。我计划让单独的对象准备ThingDoer用作输入的实际数据结构。同样,每种硬件类型我都会有一个准备器对象。
然后,根据我要编译的硬件,我将在编译中包括不同的头文件(包含我需要的特定ThingDoer等)。由于在编译时会使用特定的ThingDoer和相应的输入准备器,因此我认为这些类型将在编译时已知,因此没有任何动态类型。
答案 0 :(得分:1)
您可以将模板用于静态多态性。
#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;
}
但是您的示例也可以使用(u只能转换地址,而不能转换静态对象):
#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;
}