3

下图显示了针对此问题的三个独立测试:

(我只关注声明而不是函数的定义~~)

http://i.stack.imgur.com/wYtA6.png

我想知道为什么正确的错误“'A' is an inaccessible base of 'B'”。

为什么g ++似乎通过派生类初始化对基的引用(由于受保护的继承而导致错误),

而不是像中间那样使用转换运算符将 B 转换为 A 并传入(即 0 错误和 0 警告)?

这是图片中右侧的代码:

struct A {
    A &operator=( const A & ) { return *this;  }
}a;

struct B : protected A {
    operator A() {  return A();  };
}b;

int main( void )
{
    a = b;
    return 0;
}

谢谢你的帮助!~

4

2 回答 2

4

当您在类a = b;main()或类外(在世界上)编写时,转换发生在那里,而不是类内,并且可访问性规则适用于转换点(在类外)。为了进行这种转换,需要从外部(世界)访问基类。

在您的情况下,因为B是从Ausingprotected关键字派生的,这意味着世界无法访问A的子对象b,因此它无法转换BA。这一切的发生是因为B(which is A) 的基础由于protected继承而无法从世界访问。做到这一点public,转换也将在世界上发生。

现在,这个问题:

为什么不使用用户转换函数而不是继承转换?

由于继承转换优先于用户定义的转换函数,您可以将此首选项视为第一步,第二步是可访问性规则,转换失败!

于 2013-01-02T05:12:42.927 回答
2

第 12.3.2 节:

转换函数永远不会用于将(可能是 cv 限定的)对象转换为(可能是 cv 限定的)相同的对象类型(或对它的引用),转换为该类型的(可能是 cv 限定的)基类(或对它的引用)或(可能是 cv 限定的)void。

此外,除了少数例外,public//的选择很少会改变程序的功能,只是程序是否有效。因此,初始化尽可能直接绑定对子对象的引用,而不是使用用户定义的转换,并且在做出选择之后,编译器会检查访问。protectedprivate

于 2013-01-02T05:16:37.670 回答