避免向下转型

6
如何在使用接口时避免向下转型?我已经阅读了一些stackoverflow上的答案,如果你必须向下转型,那么你很可能有一个弱接口。那么你们是如何处理它的,什么是正确的方式?我有一个具体的例子,我想知道如何避免向下转型。在我的例子中,我有一个用于传递数据的接口,但具体实现可能包含独特的属性。在A类和B类中,我需要向下转型为DataType1或DataType2,因为它们可能返回不同类型的属性。
struct IData
{
    virtual ~IData();
};

struct IAction
{
    virtual ~IAction();
    virtual void setup(IData& data) = 0;
};

class DataType1 : public IData
{
    int data1;
public:
    DataType1();
    int getData1();
};

class DataType2 : public IData
{
    std::string data2;
public:
    DataType2();
    std::string getData2();
};

class A : public IAction
{
public:
    A();
    void setup(IData& data) override;
}

class B : public IAction
{
public:
    B();
    void setup(IData& data) override;
}

2
IData 应该提供所需的方法(可以返回数据,或返回另一个返回数据的接口)。 - M.M
3
这个问题适合在https://softwareengineering.stackexchange.com/ (设计模式)上提问。 - M.M
9
我会翻译这段话,请问为什么您希望它们有一个共同的接口?它们显然是不同的类型,为什么不只编写重载函数,以接受不同类型的数据参数呢? - Galik
3
初始化永远不可能是100%通用的,因为至少需要实例化一个特定类型。因此,当您创建对象时,必须知道其完整类型。这通常是初始化对象的时候。每个不同的类型都可以根据其自身的特定特点进行初始化。只有在此之后,您才能将其传递给那些不需要知道其确切类型的系统部分。 - Galik
2
如果你真的想要一种通用的初始化方式,那么如果你是从一个常见类型(比如文件或文本字符串)进行初始化,就可以通过一个公共接口来实现。每种类型都接收相同的输入,但根据自己的需要进行解析。这意味着 IData 将是一个固定的类型。然后你就可以避免向下转换。 - Galik
显示剩余9条评论
2个回答

0

在我看来,在代码中有一个下转指令并不是一个大问题。据我所知,这个问题是有效的,这也是为什么C++有dynamic_cast<>操作。


0

你的接口应该定义所有需要在子类上调用的方法作为虚方法(最好是纯虚方法)。

在这种情况下,你的接口可以有两个虚方法 getData 或者如果你使用 c++17 或更高版本,你可以尝试使用 std::any


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接