我有一点设计问题。
假设我有这个界面:
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技术。
答案 0 :(得分:1)
问题在于我实施的
DoSomethingWithData
方法 - 我需要引用DData
中的特定成员,但我不能因为指针属于IData
。
您正在传递指向IData
的指针,DData
是DData
的基类。通过虚函数调度,您可以通过指向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;
};
我认为这是这种情况下的最佳解决方案,因为它不需要任何人从空接口派生,并且它确实声明了一些结构。
如果有人对此解决方案有任何保留,我想听听。