免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3946 | 回复: 13
打印 上一主题 下一主题

[C++] 基类指针变量都被赋值派生类的地址,但为什么不相等呢? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-10-06 13:39 |只看该作者 |倒序浏览
#include <stdio.h>
#include <iostream>
using namespace std;


class A
{
public:
        int n;
        virtual  void fun()
        {
                cout<<"A"<<endl;
        }
};


class B
{
public:
        int n;
        virtual  void fun()
        {
                cout<<"B"<<endl;
        }
};

class C : public A, public B
{
public:
        int n;
        virtual  void fun()
        {
                cout<<"C"<<endl;
        }
};


void main()
{
        C    c;
        A*   pa = &c;
        B*   pb = &c;
        //A*   pa = static_cast<B*>(&b);

        c.fun();
        pa->fun();
        pb->fun();

        cout<<"&c = "<<&c<<endl;
        cout<<"pa = "<<pa<<endl;
        cout<<"pb = "<<pb<<endl;

        return;

}


输出:

C
C
C
&c = 0012FF6C
pa = 0012FF6C
pb = 0012FF74


为什么 &c 和 pa 相等,pb 不等?

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
2 [报告]
发表于 2012-10-08 11:07 |只看该作者
  1. B*   pb = reinterpret_cast<B*>(&c);
复制代码
这样就可以了, 禁止编译器根据父类类型变换地址.

论坛徽章:
0
3 [报告]
发表于 2012-10-08 11:32 |只看该作者
从运行结果看,pa与pb的地址差应该是int的长度吧。也很疑惑
继续关注,。!

论坛徽章:
0
4 [报告]
发表于 2012-10-08 11:45 |只看该作者
本帖最后由 cppfans6 于 2012-10-08 11:47 编辑

回复 2# linux_c_py_php


   这样是可以了,但是

B*   pb = &c;



B*   pb = reinterpret_cast<B*>(&c);

都能保证pb->fun(); 调用的还是C的fun,编译器怎么处理的?

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
5 [报告]
发表于 2012-10-08 11:58 |只看该作者
B是C的基类, 虚函数不调用C的调用谁的?

论坛徽章:
0
6 [报告]
发表于 2012-10-08 12:03 |只看该作者
linux_c_py_php 发表于 2012-10-08 11:58
B是C的基类, 虚函数不调用C的调用谁的?


这个我知道,我问的是

B*   pb = &c;  和  B*   pb = reinterpret_cast<B*>(&c);

两个pb数值不同,但还都能保证pb->fun(); 调用的是C的fun,编译器怎么处理的?

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
7 [报告]
发表于 2012-10-08 12:12 |只看该作者
本帖最后由 linux_c_py_php 于 2012-10-08 12:12 编辑

前者指向B基类, 后者指向A基类, 最后都是调C派生类, 而且A, B长的一样, 不费解吧.

论坛徽章:
0
8 [报告]
发表于 2012-10-08 12:16 |只看该作者
linux_c_py_php 发表于 2012-10-08 12:12
前者指向B基类, 后者指向A基类, 最后都是调C派生类, 而且A, B长的一样, 不费解吧.


不明白,你这个回答好像不是我要问的,请详解。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
9 [报告]
发表于 2012-10-08 12:21 |只看该作者
就是A类和B类一模一样, 第二个转换其实是将C对象中A对象的地址赋值给B的指针, 对于B指针来说, 因为A对象和B对象的内存布局是一样的, 所以调用B->xxx和调用A->xxx是一样的.

cppfans6 发表于 2012-10-08 12:16
不明白,你这个回答好像不是我要问的,请详解。

论坛徽章:
0
10 [报告]
发表于 2012-10-08 12:28 |只看该作者
linux_c_py_php 发表于 2012-10-08 12:21
就是A类和B类一模一样, 第二个转换其实是将C对象中A对象的地址赋值给B的指针, 对于B指针来说, 因为A对象和B ...


即使A和B的内存布局不一样(如下面),也是同样的啊。

class A
{
public:
        int n;
        int m;
        int k;
        virtual  void fun()
        {
                cout<<"A"<<endl;
        }
};


class B
{
public:
        char  c;
        virtual  void fun()
        {
                cout<<"B"<<endl;
        }
};
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP