【发布时间】:2017-10-27 14:28:06
【问题描述】:
我的问题是为什么下面的代码会这样。我不是在问设计的质量(我知道你们中的一些人会立即讨厌多重继承,我在这里不是支持或反对它)我可以问一个单独的问题,该问题涉及作者试图实现,但我们假设有与此等效的代码:-
class IReadableData
{
public: virtual int getX() const = 0;
};
class Data : public virtual IReadableData
{
public:
virtual int getX() const { return m_x; }
void setX(int x) {m_x = x;}
private:
int m_x;
};
class ReadableData : private Data, public virtual IReadableData
{
// I'd expected to need a using here to expose Data::getX
};
这符合 Visual Studio 2017 的“警告 C4250:'ReadableData':通过支配继承 'Data::Data::getX'”
首先我有点惊讶的是没有被告知 ReadableData 没有实现 getX(因为它的实现是私有的),但是没有出现警告,我可以创建一个 ReadableData,但是尽管 ReadableData 公开继承自 IReadableData,公共方法的 IReadableData 无法访问
ReadableData r;
// r.getX(); error C2247: 'Data::getX' not accessible because 'ReadableData' uses 'private' to inherit from 'Data'
但是以下确实编译
ReadableData r;
IReadableData& r2 = r;
r2.getX();
这对我来说似乎不一致,要么 r 是 IReadableData 并且 getX 应该可用,要么不可用,并且分配给 r2(或 ReadableData 的定义)应该失败。这应该发生吗?标准中的什么导致了这种情况?
这个问题:- Diamond inheritance with mixed inheritance modifers (protected / private / public)
似乎是有联系的,除了这种情况下的基础不是抽象的,它引用第 11.6 节的答案会让我认为 r.getX();应该是可以访问的。
编辑:我让示例代码稍微少了一点,以便对意图有一点了解,但这并没有真正改变问题。
【问题讨论】:
-
我很困惑...您想说“ReadableData 具有接口 IReadableData,但实现 Data”?这只是数据,你 typedef 它。
-
@UKMonkey 这是一个最小的例子,它不是真正的代码。
-
@Ron,“避免多重继承”?接口呢?甚至 C# 也允许这样做(尽管它不允许私有继承)。
-
通常的做法是拥有一个私有的Data成员,然后ReadableData的impl封装了Data函数。继承的问题不在于多重部分,而在于它们在不应该这样做的时候这样做。
-
@UKMonkey,谢谢,是的,我同意,这就是我自己通常会这样做的方式。我仍然想了解为什么这样的代码会表现得如此。