由多重继承导致的“无法访问的直接基础” [英] 'Inaccessible direct base' caused by multiple inheritance

查看:190
本文介绍了由多重继承导致的“无法访问的直接基础”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Spoiler警报:也许是一个愚蠢的问题。 :)

Spoiler alert: Maybe a stupid question. :)

#include <iostream>

using namespace std;

class Base
{
    public:
        virtual void YourMethod(int) const = 0;
};

class Intermediate : private Base
{
    public:
        virtual void YourMethod(int i) const
        {
            cout << "Calling from Intermediate" << i << "\n";
        }
};

class Derived : private Intermediate, public Base
{
    public:
        void YourMethod(int i) const
        {
            cout << "Calling from Derived : " << i << "\n";
        }
};

int main()
{
}

有人可以向我解释为什么会抛出编译器警告

Can someone Explain to me why this throws the compiler warning:

main.cpp:21: warning: direct base ‘Base’ inaccessible in ‘Derived’ due to ambiguity

现在,我明白这个代码没有办法。我想知道为什么。 基本中间的私有属性,因此它不应显示给派生通过中间。那么歧义来自哪里?在构造函数中?

Now, I understand that there is no way this code will work. I want to know why. Base is private to Intermediate so it should not be visible to Derived through Intermediate. So where does the ambiguity come from? In constructor?

推荐答案

这与覆盖函数无关。它与转化有关。它真的不必直接与可访问性(即私人等)。这里是一个更简单的例子

This has nothing to do with overriding functions. It has to do with conversions. It really doesn't have to do with accessibility (i.e "private" or such) directly either. Here is a simpler example

struct A { int a; };
struct B : A { };
struct C : B, A { }; // direct A can't be referred to!

您可以参考间接的 A 对象首先转换为 B ,然后转换为 A

You can refer to the indirect A object by first converting to B and then to A:

B *b = &somec;
A *a = b;

不能使用直接A对象。如果您尝试直接转换为 A ,它将有两种可能性。因此,在给定 Derived 对象的情况下,不可能引用直接 A 对象的非静态数据成员。

You cannot do such with the direct A object. If you try to directly convert to A, it will have two possibilities. It follows that it is impossible to refer to the non-static data members of the direct A object given a Derived object.

请注意,辅助功能与可见性正交。即使它不可见也可以访问某些东西(例如通过用限定名称引用它),并且即使它不可访问,某些东西也是可见的。即使所有上面的推导声明为 private ,问题仍然会出现:Access最后检查 - 它不会影响名称查找或转换规则。

Notice that accessibility is orthogonal to visibility. Something can be accessible even tho it's not visible (for example by refering to it by a qualified name), and something can be visible even though it's not accessible. Even if all the above derivations would be declared private, the problem would still show up: Access is checked last - it won't influence name lookup or conversion rules.

此外,任何人都可以使用C风格的转型,转换为具有定义行为(C ++标准对此做出异常)的无歧义的私有基类,即使正常访问将不会批准这样做。然后还有朋友和类本身可以自由转换。

Also, anyone can cast to an unambiguous private base class with defined behavior (the C++ Standard makes an exception for this) using a C-style cast, even if normally access wouldn't be granted to do so. And then there are still friends and the class itself that could freely convert.

这篇关于由多重继承导致的“无法访问的直接基础”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆