C++多态 重写 重载 隐藏之间的关系

C++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。

重写:子类重定义基类中的virtual函数,通过子类指针或引用指向子类对象时,调用的是子类中的的函数。

重载:一个类内部的具有不同形参的函数构成重载,不涉及基类和子类。

隐藏这里“隐藏”是指派生类的函数屏蔽了与其同名的基类函数或成员变量

对于基类子类同名函数来说,只要不是virtual重写,其他的子类同名函数都将隐藏基类的同名函数,即:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual
关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual
关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)。

下面贴一段代码:

#include 
#include 
using namespace std;

class TestA{
public:
    TestA():mCount(0){}
    virtual ~TestA() {printf("release A\n");}
public:
    virtual void init() {printf("this is A init\n");mCount = 5/10;}
    virtual void increment() {printf("this is A++\n"); mCount++;}
    virtual void print() {printf("this is A, count = %d\n",mCount);}
private:
    int mCount;
};
class TestB : public TestA{
public:
    TestB():mCount(0){}
    virtual ~TestB() {printf("release B\n");}
public:
    virtual void init() {printf("this is B init\n");mCount = 10;}
    virtual void print() {printf("this is B, count = %d\n",mCount);}
private:
    int mCount;
};
int main(void)
{
    TestB *pB = new TestB();
    pB->init();  // mCount = 10
    pB->increment();//重点在这里,TestB中并没重写虚函数increment ,调用了TestA中
                    //函数,并且使TestA::mCount数据成员自增+1, 然后再调用TestB中的打印
                    // TestB::mCount 为10,并不是11, 这里要分清楚是哪一个数据成员
    pB->print();   //打印的是TestB中的mCount 10


    TestA *pA = (TestA*)pB;// 这里涉及到多态,当用基类的指针指向派生类对象时,派生类中有虚函数,则会有一个虚指针,
    //在分配的TestB内存块的最开头的前四个字节,指向TestB中存在的虚函数首地址,
    //可以在内存中用看pB的值,然后看内存,前四个字节为虚指针,
    //所以pA指向了pB的虚指针所在内存块的地址,因此这里和上面情况其实是一样的
    pA->init();//TestB::mCount为10
    pA->increment();//TestA::mCount + 1
    pA->print();//打印的是TestB中的mCount 10


    TestA aA = *pB;//此处将*pB中已经对TeseA中的数据成员初始化了,并且将该值给了aA中的数据成员
                //下面都是调用TestA中的函数
    aA.print();//这里TestA::mCount为2
    aA.init(); //TestA::mCount又被重置0
    aA.increment();//TestA::mCount + 1
    aA.print();//TestA::mCount 为 1

    delete pB;// pB为派生类对象指针,且TestA和TestB的析构均为虚析构,

            // 会先调用B的析构,然后A的析构, 最后应用程序结束时,调用aA的析构函数

            //   即Release B  ReleaseA ReleaseA
}
结果:

C++多态 重写 重载 隐藏之间的关系_第1张图片
如果还不懂,可以参考以下两篇文章:

http://blog.csdn.net/hackbuteer1/article/details/7475622

http://blog.csdn.net/foruok/article/details/37996805

你可能感兴趣的:(c++)