设计一个具有适当的Base类指针声明的接口--cpp

时间:2018-01-10 08:51:35

标签: c++ design-patterns interface

我有一点设计问题。

假设我有这个界面:

class IBase {
public:
    virtual void Run() = 0;
    virtual void DoSomethingWithData(IData* data) = 0;
    virtual ~IBase() = 0;
};

我想实现派生类,所以我需要为IData构建一个派生类(让我们称之为DData)。 IData基本上是一个空接口:

class IData {
public:
    IData();
    virtual ~IData() = 0;
};

问题在于我实现的DoSomethingWithData方法 - 我需要在DData中引用特定成员,但我不能因为指针是IData。例如,请参阅某些派生类中的DoSomethingWithData实现:

class DData : public IData {
private:
    int m_i;
};

<Derived.h : IBase>
Derived::DoSomethingWithData(IData* data) {
    some_function_call(data->m_i) // cannot be used by the base ptr
}

解决这个问题的最佳方法是什么?

在SetData上进行动态转换? 更改界面(以这种方式?)? 其他选择?

修改

澄清问题: 我有这种关系 -

class A -> uses DataA
class B -> uses DataB
class C -> uses DataC

这些类有一个通用接口:Run,DoSomethingWithData。 DoSomethingWithData期望数据,但它不知道什么是数据,它取决于我们实现的类。 我需要找到编写接口的最佳方法,而不使用像dynamic_cast那样糟糕的OOP技术。

3 个答案:

答案 0 :(得分:1)

  

问题在于我实施的DoSomethingWithData方法 - 我需要引用DData中的特定成员,但我不能因为指针属于IData

您正在传递指向IData的指针,DDataDData的基类。通过虚函数调度,您可以通过指向IData的指针调用实际在DData中实现的成员函数。

IData派生自IData,因此您可以在class IData { public: IData(); virtual int getData() = 0; // <-- new virtual function virtual ~IData() = 0; }; 中声明虚拟成员函数

DData

然后class DData : public IData { public: int getData() override { // <-- implementation return m_i; } private: int m_i; }; 中实现此函数:

DData

由于该成员函数在m_i中实现,因此它可以访问其私有数据成员(即:getData())。

当您通过DData指针呼叫IData个实例的DData时,您将使用NO_ZERO_IN_DATE,NO_ZERO_DATE的实施。

答案 1 :(得分:1)

  

我需要引用DData中的特定成员,但我不能因为指针是IData

接口指定合同。它不知道&#34;关于内部细节/表示(例如,成员变量,私人函数等)如果您的IData必须&#34;知道&#34;关于DData的私有成员变量,你做错了什么。也许使用Data的接口是错误的。如果Data意味着是POD(普通ol&#39;数据)结构,那么只需让您的基类采用Data并公开处理所述结构的API。

答案 2 :(得分:0)

我们选择的解决方案是使用模板(我不明白为什么没有人建议)。

template <class T>
class IBase {
public:
    virtual void Run() = 0;
    virtual void DoSomethingWithData(const T& data) = 0;
    virtual ~IBase() = 0;
};

我认为这是这种情况下的最佳解决方案,因为它不需要任何人从空接口派生,并且它确实声明了一些结构。

如果有人对此解决方案有任何保留,我想听听。