【问题标题】:private inheritance, friends, and exception-handling私有继承、朋友和异常处理
【发布时间】:2011-04-23 09:49:39
【问题描述】:

当A类从B类私有继承时,这意味着B是A的私有基类子对象。但对朋友来说不是,对朋友来说它是一个公共子对象。并且当有多个 catch 处理程序时,将调用第一个匹配的(即,如果异常类型可以隐式转换为处理程序的参数类型)。那么有人会向我解释为什么下面的代码不能按我的预期工作吗?这种行为是标准的意图还是这是一个 MSVC 错误?

class A
{
};
class B:A //private inheritance 
{
    friend void g();
}; 

void f()
{

    B b;
    //A* pa = &b; // error, conversion exists, but is inaccessible
    throw b;
}

void g()
{
    B b;
    A* pa = &b; //ok, private inheritance, but g() is B's friend so it is as though public
    try
    {
        f();
    }
    catch(A&)
    {
        //WHY ISN'T THIS HANDLER INVOKED?! B&->A& conversion exists in this function
    }
    catch(B&)
    {       
    }
}

int main()
{
    g();
}

附:这不是真正的代码,这是一个理论实验,也就是说,不要告诉我朋友不好,组合优于私有继承之类的东西。

提前致谢

【问题讨论】:

  • 亲爱的,你的概念完全错误
  • @yosanu:到底是哪个概念,亲爱的?
  • 在 gcc 中也无法正常工作,因此可能不是编译器错误。
  • @David thanx,这是个好消息。但我仍然希望从标准和基本原理中得到一个扩展的答案:)

标签: c++ inheritance exception-handling friend


【解决方案1】:

不,这不是标准所说的。它说(C++0x):

处理程序是异常的匹配项 类型 E 的对象 if

— 处理程序的类型为 cv T 或 cv T& 和 E 和 T 是同一类型 (忽略顶级 cv 限定符), 或

— 处理程序的类型为 cv T 或 cv T& 并且 T 是一个明确的公共基础 E 类,或

— 处理程序的类型为 cv1 T* cv2 E 是一个指针类型,可以 转换为处理程序的类型 通过其中一个或两个

     - 标准指针转换 (4.10) 不涉及到指针的转换 私有或受保护或模棱两可 类

    - 资格转换

——处理程序是一个指针或指向 成员类型和 E 是 std::nullptr_t

理由:复杂的实现。您可以将其视为发生在 throw 和 catch 之间的转换,而不是 g 本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多