为什么'using A::X'不避免多重继承的歧义?



这与这个问题和这个问题相似,但我认为(希望!(足够不同,值得解释。

我有一个复杂的配置框架,decorator类用于实现一些常见的、简单的操作(比如在调用类Set访问器时进行标记(。我试图引入一个新的装饰器(而不是一个组合(;应该";从同一个共同的"继承";设置标记";室内装修设计师

我遇到了";从派生类到基类的模糊转换";,我试图解决这个问题的努力都失败了。我肯定错过了一些显而易见的东西。

这里有一个非常简单的例子,没有我所有的框架内容。

class A {
public:
template <class T> void Set(T& arg, T val);
bool Ready() const;
};
class B : private A {
// Does stuff where I want to flag Set() actions
};
class C : public B, public A {
// This class needs the B interface, and the Set()-flagging
public:
void SetParam(double val) { Set(param, val); }
private:
double param;
};

注意,我最初使用了A的虚拟继承,但在实践中我需要保留";设置标志";对于不同于"A"的B;设置标志";对于C,因此我在上面进行了尝试。

上面的私人继承是我第一次尝试避免歧义。我还尝试在C:中引入使用指令

class C : public B, public A {
// This class needs the B interface, and the Set()-flagging
using A::Set;
using A::Ready;
};

这不会改变错误。我从搜索中了解到,在检查公共/私人状态之前就发现了模糊性。但我认为明确的using指令会解决这个问题。为什么不解决呢?我是否需要进入并在任何地方显式使用A::Set(...)A::Ready()

两个解决方案。

如果你真的想保留私有和多重继承:

class A {
public:
void Set() {};
bool Ready() const {};
};
class B : private A {
};
class C : public B, public A {
public:
void SetParam() { C::A::Set(); }
};

或者,如果不需要,那么一个更简单的方法:

class A {
public:
void Set() {};
bool Ready() const {};
};
class B : public A {
};
class C : public B {
public:
void SetParam() { Set(); }
};

最新更新