[C++]名字查找与作用域

【概念】

a) 作用域

作用域有大小之分。比如全局作用域大于局部作用域,这个很显然。要强调的是另一点:基类作用域大于派生类作用域。可能有人会有疑问,这两个作用域看不见摸不到,怎么知道大小?但是其实仔细想想,这很符合现实世界的面向对象模型:鱼的作用域显然要比金鱼大,交通工具的作用域肯定要比飞机大。如果你实在理解不了,那你还是就这么记住吧。

b) 名字查找

请注意,这里的名字仅仅是指函数的名字,而不是原型!名字相同,查找即成功。这是个跟作用域密切相关的概念。名字查找符合以下的过程:

1 .根据对象,指针,引用的静态版本决定哪一个函数被调用。
2 .到相应的中查找,如果没有找到,则到该类的直接基类中查找,按此过程下去都没找到,报错。
3 .找到,做原型检查,看调用是否正确。
4 .正确,判断是否动态绑定,调用相应版本。

这个过程概括就是:先静态,后动态;作用域从小至大。

======================================================

[举例]

下面举几个例子来说明这种情况。

(1)下面这个例子说明了名字查找只根据静态类型查找(即使是指针调用,也只看指针的静态类型)。也可以从另一个角度理解这个问题:

“虚函数必须在基类和派生类中拥有同一原型”。 所以,Derived类中的func()其实已经不是虚函数了,所以其实不能提供多态的性质。当然,Derived类中仍然有虚函数指针(Derived类对象的size都是4),其中存的是base::func()。

#include <iostream>

using namespace std;

class
Base
{
public
:
    
virtual void func(double i){ cout<<"in base\n"
; }
};

class Derived : public
Base
{
public
:
    
void func(){ cout<<"in derived\n"
; }
};

int main(void
)
{
     Base b;
     Derived d;

     Base
*pb = &
d;
     Derived
*pd = &
d;

     b.func(
3.14
);
    
//b.func();    //
compile error

    
//d.func(3.14);    //compile error

     d.func();

     pb
->func(3.14
);
    
//pb->func();    //
compile error : can't find func() in Base

    
//pd->func(3.14);    //compile error : can't find func(double) in Derived

     pd-> func();
}

(2)下面是《C++ Primer》书中的经典例子。

class Base
{
public
:
    
virtual int
fcn();
};

class Derived1 : public
Base
{
public
:
    
//hides Base::fcn(), this fcn(int) is not virtual

    int fcn(int );
    
//Derived1 inherits definition of Base::fcn()

};

class Derived2 : public
Derived1
{
public
:
    
int fcn(int);//nonvirtual function hides Derived1::fcn(int)

    int fcn();//redefine virtual Base::fcn()
};

请读者自行理解。






转载于:https://www.cnblogs.com/microgrape/archive/2011/05/11/2043789.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值