【问题标题】:Downcasting and Virtual Functions向下转换和虚函数
【发布时间】:2015-08-03 08:09:00
【问题描述】:

我在一次采访中被问到这个问题,我不确定在以下情况下的行为:

class A 
{ 
      virtual fun1(){...}
      virtual fun2(){...}
};

class B : public A
{ 
      virtual fun1(){...}
      virtual fun2(){...}
};

现在如果,

A* AObj = new A;
B* BObj = (B*) AObj;

BObj 是否可以访问 B 的方法是因为 virtual 关键字,还是因为它指向 AObj 的对象?

有人可以帮助我了解向下转换究竟是如何影响访问的吗?

【问题讨论】:

  • 您可以在 ideone.com 或任何地方尝试:ideone.com/B7P6DN(这给了我运行时错误)

标签: c++ inheritance polymorphism downcast


【解决方案1】:

将基类对象的地址分配给派生类指针是undefined behavior。所以任何事情都可能发生:调用BObj 的函数可以调用B 的函数,可以调用A 的函数,可以使程序崩溃,甚至可以格式化您的硬盘。这完全取决于编译器及其优化选项。

【讨论】:

    【解决方案2】:

    首先,这样做

    A* AObj = new AObj();
    
    B* BObj = AObj;
    

    根本不安全,因为它将基类对象(Parent)的地址分配给派生类(Child)指针。因此,代码会期望基类对象具有派生类属性。

    但是你可以这样做:

        A* AObj = new AObj();
    
        B* BObj = dynamic_cast<B*>AObj;
    

    这将检查是否可以将 Aobj 分配给 Bobj。如果可以,则返回对象的地址,否则返回0。

    所以你可以像这样使用它:

    B* BObj = dynamic_cast<B*>AObj;
    if(BObj)
    {
        //Now you can use it safely.
    }
    

    【讨论】:

    • 从语法上讲,您提出了一个有效的观点,我将相应地编辑我的问题。但这是我有点模糊的方法访问。谢谢!
    • @VishnuNair 正如 Petr 正确指出的那样,这是未定义的行为,当我说它不安全时,我的意思是相同的,使用 BObj 可能会或可能不会访问 B 的函数,或者它可能会使代码崩溃。
    • @VishnuNair 如果 dynamic_cast 找到,可以安全地转换对象,它会转换并返回地址,现在如果派生类中定义了额外的函数,你会得到一个 NULL。跨度>
    【解决方案3】:

    在这种情况下(多态性),指针的类型(BObj,这里它的类型不是 B)就是它指向的对象的类型(A)。 所以 BObj 是基类的对象,不能做额外的工作(函数)在派生类 (B) 中定义。

    【讨论】:

    • 如果此答案解决了您的问题(清除了概念),请将其标记为答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    相关资源
    最近更新 更多