zoukankan      html  css  js  c++  java
  • 【C/C++】关于C++的名字查找与继承

    为了将问题简化,首先来看一段代码:

    #include <tchar.h>
    #include "stdio.h"
    
    class A
    {
    public:
        void func()
        {
            printf("A::func\n");
        }
    };
    
    class B : public A
    {
    public:
        void func(int n)    // 注意这里func与A的func同名,但参数不同
        {
            printf("B::func\n");
        }
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        B b;
        b.func();    // 期望调用B的基类A的func()函数
        return 0;
    }

    这里本来是期望调用A::func()函数,但很抱歉,编译器不会如您所愿,编译器会报错:

    1>f:\testproj\consoletest_vs2005\test\test.cpp(25) : error C2660: 'B::func' : function does not take 0 arguments

    这是什么原因呢?翻阅C++ Primer可以得到答案:

    C++ Primer 中文第四版P500的注解:如果派生类重定义了重载成员,则通过派生类型只能访问派生类中重定义的那些成员。

    为什么会这样?要理解这个问题就需要知道了解C++中名字查找与继承(C++ Primer 中文第四版P501的关键概念):

    确定函数调用遵循以下四个步骤:

    1.首先确定进行函数调用的对象、引用或指针的静态类型。

    2.在该类中查找函数,如果找不到,就在直接基类中查找,如此循着类的继承往上找,直到找到该函数或者查找完最后一个类。如果不能在类或其相关基类中找到该名字,则调用是错误的。

    3.一旦找到了该名字,就进行常规类型检查(7.1.2节),查看如果给定找到的定义,该函数是否合法。

    4.假定函数合法,编译器就生成代码。如果函数是虚函数且通过引用或指针调用,则编译器生成代码以确定根据对象的动态类型运行哪个函数版本,否则,编译器生成代码直接调用函数。

    以上就是这个问题的解释。

  • 相关阅读:
    hdu5926Mr. Frog’s Game
    hdu5926Mr. Frog’s Game
    hdu5924Mr. Frog’s Problem
    hdu5924Mr. Frog’s Problem
    hdu5922Minimum’s Revenge
    hdu5922Minimum’s Revenge
    带空格的字符串输入
    带空格的字符串输入
    382. Linked List Random Node
    319. Bulb Switcher
  • 原文地址:https://www.cnblogs.com/jeJee/p/2695000.html
Copyright © 2011-2022 走看看