这段代码的error产生原因是什么?

本文详细解读了C++中继承与虚函数调用的过程,包括如何确定函数调用、查找过程以及错误处理机制。以实例分析,帮助开发者理解在继承层次中调用函数时的常见问题及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
using namespace std;

class Base{
public:
    virtual int call()
    {
        int a = 2;
        cout << "Base " << a << endl;
        return a;
    }
};

class D1:public Base{
public:
    int call(int a)
    {
        cout << "D1 " << a << endl;
        return a;
    }
};

class D2:public D1{
public:
    int call()
    {
        int a = 3;
        cout << "D2 " << a << endl;
        return a;
    }

    int call(int a)
    {
        cout << "D2 " << a << endl;
        return a;
    }
};

int main()
{
    D1 d1;
    d1.call();// error: no matching function for call to 'D1::call()',why?

    D2 d2;
    d2.call();//ok

    Base bobj;  D1 d1obj;  D2 d2obj;
    Base *bp1 = &bobj, *bp2 = &d1obj, *bp3 = &d2obj;
    bp1->call();   // ok: virtual call, will call Base::call at run time
    bp2->call();   // ok: virtual call, will call Base::call at run time
    bp3->call();   // ok: virtual call, will call D2::call at run time

    int i;
    cin >> i;
}

参考下面空白理解:

关键概念:名字查找与继承

Understanding how function calls are resolved is crucial to understanding inheritance hierarchies in C++. The following four steps are followed:

理解 C++ 中继承层次的关键在于理解如何确定函数调用。确定函数调用遵循以下四个步骤:

1.
Start by determining the static type of the object, reference, or pointer through which the function is called.
首先确定进行函数调用的对象、引用或指针的静态类型。
2.
Look for the function in that class. If it is not found, look in the immediate base class and continue up the chain of classes until either the function is found or the last class is searched. If the name is not found in the class or its enclosing base classes, then the call is in error.
在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承链往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关基类中找到该名字,则调用是错误的。
3.
Once the name is found, do normal type-checking to see if this call is legal given the definition that was found.
一旦找到了该名字,就进行常规类型检查,查看如果给定找到的定义,该函数调用是否合法。
4.
Assuming the call is legal, the compiler generates code. If the function is virtual and the call is through a reference or pointer, then the compiler generates code to determine which version to run based on the dynamic type of the object. Otherwise, the compiler generates code to call the function directly.
假定函数调用合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。


关键点:这个错误发生在编译时,d1调用的call编译器在编译时会在d1的作用域内查找,结果被编译器找到了,所以它就不会再网上去查找call了,但此处的call(int),所以调用不匹配就报错了。派生类要么重定义所有重载版本,要么一个也不重定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值