c++ - 在抽象基类定义中使用未知类型

标签 c++ oop

我有一个抽象基类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]);
    }
};

我试过让 FooBar 都继承自另一个基数据类:(我改变了实际发生的情况以稍微简化示例)

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/

相关文章:

c++ - 可以使用 -fsanitize=address 运行 MEX 文件吗?

c++ - 二维数组 - 创建虚拟生物? (C++)

Python 结构问题 : Giving an 'engine' class to everything

java - 如何从同一个类中的另一个方法调用一个方法(java)

oop - 仅具有两个属性的对象

c# - c# 中的链表和红/黑树 - 引用问题?

c++ - 在派生类中声明为非虚函数的虚函数

c++ - 在 AXP 服务器上编译的问题

c++ - 多态性或条件会促进更好的设计吗?

php - 类扩展自身?