鱼C论坛

 找回密码
 立即注册
查看: 2490|回复: 6

C++类中只有通过指针调用函数的时候才能形成覆盖的效果吗

[复制链接]
发表于 2016-8-18 17:40:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 wenmingxing 于 2016-8-18 17:42 编辑

C++ 类中只有通过指针调用函数才能形成   覆盖   吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-8-18 18:42:28 | 显示全部楼层
不大明白你的意思, 可以说清楚些吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-18 19:31:23 | 显示全部楼层
浅云纸月 发表于 2016-8-18 18:42
不大明白你的意思, 可以说清楚些吗

就是只有通过指针的形式调用函数才能形成覆盖基类函数的效果吗,如果不通过指针调用那直接通过a.fun这种形式不就相当于基类函数没有被覆盖吗
#include<iostream>

using namespace std;

class A
{
public :
    virtual void play();
};

class B : public A
{
public :
    void play();
};

void A :: play()
{
    cout << "AAA" << endl;
}

void B :: play()
{
    cout << "BBB" << endl;
}

main()
{
    A a;
    B b;

    a.play();           //不覆盖

    A *aa;
    aa=&b;

    aa -> play();             //覆盖
}

上面例子main中的a.play就是没有覆盖效果输出AAA,a->play覆盖输出BBB
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-18 20:59:24 | 显示全部楼层
本帖最后由 浅云纸月 于 2016-8-19 22:46 编辑

直接在外部调用基类A的函数也可以实现 ...  不过确实可以实现, 会麻烦一点.  我写了下代码, 你看一下, 不懂的尽管问
#include "stdafx.h"
#include <iostream>

#include <windows.h>


using namespace std;

class A
{
public:
        virtual void play();
};

class B : public A
{
public:
        void play();
};

void A::play()
{
        
        cout << "AAA" << endl;
}

void B::play()
{
        cout << "BBB" << endl;
}

int main()
{
        // 获取类 A 的 vftable
        struct tagCLASS
        {
                DWORD *pVMT;
        };
        A a;
        DWORD *pVMT = ((tagCLASS *)(&a))->pVMT;

        // 获取 vftable 中的 play() 函数的内存地址
        static void(__fastcall *pfnA_Play)(void *pthis) = NULL;
        pfnA_Play = (void(__fastcall *)(void *pthis))pVMT[0];

        B b;
        A* aa = &b;

        // 调用 类A 的play()函数
        pfnA_Play(aa);

    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-19 22:26:34 | 显示全部楼层
其实应该是指针和引用都可以的,在使用虚函数的前提下可以实现动态编联,能够正确的调用对象的函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-19 23:10:51 | 显示全部楼层
这就要从汇编层面上看了:每一个对象头部4Bytes指向虚函数表,对象A和对象B都有一个虚函数表,如果用指针P的话,P指向A就用A的虚函数表,P指向B就用B的虚函数表,这么简单的一个东西就实现了所谓多态性。不用指针的话,用的虚函数表都是不变的,所以每一个对象用到的函数都不会变。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-21 23:20:10 | 显示全部楼层
基函数中函数声明为虚函数,在用指针调用的过程中实现动态绑定。这是面向对象语言的多态性。另外,你的代码有问题。
#include<iostream>

using namespace std;

class A
{
public :
    virtual void play();
};

class B : public A
{
public :
    void play();
};

void  A :: play()
{
    cout << "AAA" << endl;
}

void B :: play()
{
    cout << "BBB" << endl;
}

 int main()
{
    A a;
    B b;

    a.play();           //调用基类的函数,输出AAA
        b.play();                        //调用继承类的函数,输出BBB
    A *aa;
    aa=&b;                                        

    aa -> play();        //实现类的动态绑定,输出BBB
        
 }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-27 08:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表