隐藏和覆盖 C++

来源:互联网 发布:红花油好用吗网络用语 编辑:程序博客网 时间:2024/05/17 08:58
我可以给你说说我的理解  
我认为隐藏和覆盖的区别主要体现在  多态上

举个例子

隐藏和覆盖

#include<iostream>
#include<string>
using namespace std;
class A
{

      public :
      A(){}
      void f(){cout<<'a'<<endl;}
      virtual void g(){cout<<"invoke aaa"<<endl;}
};
class B:public A
{
        public:
        B(){}
        virtual void g(){cout<<"invoke bbb"<<endl;}
        void f(){cout<<'b'<<endl;}
};

int main()
{
    A * a = new B;
    A * b = new A;
    B * c = new B;
    a->f();
    b->f();
    c->f();
    cout<<"-------------------------"<<endl;
    a->g();
    b->g();
    c->g();
}
结果是 

a
b    
invoke bbb 
invoke aaa
invoke bbb

我想说的是  如果是隐藏的话  当你通过指针调用这个函数的时候,调用根据的是指针的类型

            如果是覆盖的话  当你通过指针调用这个函数的时候,根据的是指针指向的类型

这就是我的理解  希望对你有用







这涉及到多态的问题。比如说你有一个基类BASE,有一个派生类Derived继承自BASE两个类都有一个叫做fun的方法然后你创建一个子类对象,但是用父类的指针(或者引用)指向他例如:BASE *b = new Derived();如果你不加virtual那么b.fun()调用的是父类的fun。因为b是父类指针,只能调用父类的方法,调用不到子类的方法。如果你加上virtual那么b.fun()调用的是子类的fun。因为加了virtual之后,会产生一个虚表,将fun函数放入虚表之内。当创建一个子类对象时,会自动“覆盖”父类的fun函数(你暂时这么理解就行)。b.fun()调用的是子类覆盖之后的fun函数。也就是说,不加virtual,你的子类对象会有两个fun函数,一个父类的,一个子类的。如果你加上virtual,你的子类只有一个fun函数,就是父类的fun函数。简单说一下多态的作用吧。比如说ATM,你要插借记卡,信用卡,VISA之类的,各种各样的银行卡。这些卡都是银行卡,所以银行卡是父类。而各种各样的卡是子类。当ATM要取钱的时候,他不需要为每一种卡都写一个函数        借记卡.getMoney(),信用卡.getMoney()。有了多态之后,他只需要写一个 银行卡的getMoney()函数就行了,将这个函数设置为virtual。多态的意义就是能够用父类指针来指向子类对象。而不同种类的卡(子类)只需要实现自己的getMoney().当使用银行卡调用getMoney函数时,程序会因为多态性,自动寻找子类的getMoney函数执行。非常方便。
父类子类指针函数调用注意事项
1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩

2,如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义)

3,如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定

虚拟函数就是为了对“如果你以一个基础类指针指向一个衍生类对象,那么通过该指针,你只能访问基础类定义的成员函数”这条规则反其道而行之的设计。

如果你预期衍生类由可能重新定义一个成员函数,那么你就把它定义成虚拟函数( virtual )。
polymorphism就是让处理基础类别对象的程序代码能够通透的继续适当地处理衍生类对象。

纯虚拟函数:
virtual void myfunc ( ) =0;
纯虚拟函数不许定义其具体动作,它的存在只是为了在衍生类钟被重新定义。只要是拥有纯虚拟函数的类,就是抽象类,它们是不能够被实例化的只能被继承)。如果一个继承类没有改写父类中的纯虚函数,那么他也是抽象类,也不能被实例化。
抽象类不能被实例化,不过我们可以拥有指向抽象类的指针,以便于操纵各个衍生类。
虚拟函数衍生下去仍然是虚拟函数,而且还可以省略掉关键字“virtual”。

看个例子:
#include <iostream> 
using namespace std; 
class
 A 

public

    virtual void foo() 
    { 
        cout 
<< "A's foo()" << endl; 
        bar(); 
    } 

    virtual
 void bar() 
    { 
        cout 
<< "A's bar()" << endl; 
    } 
}; 
class B: public A 

public
    void foo() 
    { 
        cout 
<< "B's foo()" << endl; 
        A::foo(); 
    } 

    void
 bar() 
    { 
        cout 
<< "B's bar()" << endl; 
    } 
}; 
int main() 

    B bobj; 
    A 
*aptr = &bobj; 
    aptr
->foo(); 
    A aobj 
= *aptr; //转化为A类对象
    aobj.foo(); 
}

aptr->foo()输出结果是:
   B's foo()//这个明白,多态性
   A's foo()//这个也明白,执行A::foo();
   B's bar()//虽然调用的是这个函数:A::foo(); 但隐式传入的还是bobj 的地址,所以再次调用bar();调用时还是会调用B的函数, 与虚函数指针有关

aobj.foo()输出结果是:
  A's foo() //这个不是指针,aobj完全是一个A的对象,与多态没有关系
  A's bar() 


0 0
原创粉丝点击