【问题标题】:type conversion between inherited classes when passing an argument in C++在 C++ 中传递参数时继承类之间的类型转换
【发布时间】:2012-12-16 12:35:37
【问题描述】:

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

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

我想知道为什么正确的错误“'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;
}

感谢您的帮助!~

【问题讨论】:

    标签: c++ inheritance reference type-conversion


    【解决方案1】:

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

    在您的情况下,由于B 使用protected 关键字从A 派生,这意味着世界无法访问bA 子对象,因此它无法将B 转换为@987654329 @。这一切的发生是因为B(即A)的基础由于protected 继承而无法从世界访问。让它public,世界也会发生转化。

    现在,这个问题:

    为什么不使用用户转换函数来代替继承转换?

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

    【讨论】:

    • 问题似乎是“为什么不使用转换运算符代替子对象”,而不是“为什么子对象访问无效”...
    • @aschepler:在我看来不是这样。无论如何,将其添加到我的答案中。
    • @Nawaz:谢谢!很高兴知道这是私有/受保护继承的效果,因为我一直只看到公共继承。
    【解决方案2】:

    第 12.3.2 节:

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

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

    【讨论】:

    • 谢谢~这个答案直接指向了我的问题~也许粗体字让Nawaz一开始就忽略了下面的细节......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 2014-06-05
    • 2014-12-25
    • 2010-11-21
    • 2018-04-03
    • 1970-01-01
    • 2016-11-07
    相关资源
    最近更新 更多