【问题标题】:Virtual function in C++C++中的虚函数
【发布时间】:2016-12-02 17:07:35
【问题描述】:

在下面的 c++ 代码中使用虚函数

#include<iostream>
using namespace std;
class Base{
    public:
    virtual void fun(){
        cout << "Base::fun()called \n";
    }

};

class Child : public Base {
    public:
    void fun() {
        cout << "Child::fun() called\n";
    }

    void door(){
        cout << "Child::door() called \n";
    }
};


int main(){

    Base *base_ptr = new Child();
    base_ptr->fun();
    return 0;
}

如何使用 base_ptr 调用门函数? 这个问题是在一次采访中被问到的。 我想知道这是否可能

感谢您的回复

【问题讨论】:

  • virtual void door()=0; 添加到Base 的类声明中。还是不能修改Base?
  • @drescherjm 。不,你不能修改 Base
  • 你知道,当你看到 OOP 和类使用如此不正确时,找出你的反应可能只是一个技巧问题。

标签: c++ virtual-functions dynamic-binding


【解决方案1】:

(假设BaseChild不能修改。)

您可以使用static_castbase_ptr 转换为Child*

static_cast<Child*>(base_ptr)->door()

只要您确定base_ptr 实际上指向Child 实例,这是安全的。


如果您不知道base_ptr 指向的派生实例类型,请考虑使用dynamic_cast

if(auto child = dynamic_cast<Child*>(base_ptr))
{
    child->door();
}

除非编译器设法对其进行积极优化,否则dynamic_caststatic_cast 相比具有额外的运行时开销。

【讨论】:

  • dynamic_cast 可能更合适。
  • @FredLarson:在这种特殊情况下没有理由使用dynamic_cast
  • @VittorioRomeo:您自己在回答中指出了原因,为了使static_cast 有效,“您必须确保base_ptr 实际上指向Child 实例”。 dynamic_cast 允许您确定是否如此。
  • @BenVoigt:对于问题中提出的情况总是如此。无论如何,我更新了答案以使其更通用。
  • @FredLarson 是对的,dynamic_cast 始终是更好的选择,因为当代码更改并且原始假设不再有效时,它更能抵抗错误。只有 2 种情况会首选 static_cast:当基类中没有虚函数时,以及当您无法承受 dynamic_cast 的开销时,因为它处于紧密循环中(但您可能会这样做 @ 987654343@ 在循环之外)。
【解决方案2】:

因为Base没有door()方法,你显然不能简单地调用base_ptr-&gt;door()

但是,如果您知道 base_ptrChild,您可以转换它然后调用 door()

Child* child_ptr = static_cast<Child*>(base_ptr);
child_ptr->door();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    相关资源
    最近更新 更多