类对象成员调用的机制

#include <stdio.h>
 
class A
{
public:
    A() {m_a = 1; m_b = 2;}
    ~A() {}
    void fun() {printf("%d %d", m_a, m_b);}
private:
    int m_a;
    int m_b;
};
 
class B
{
public:
    B() {m_c = 3;}
    ~B() {}
    void fun() {printf("%d", m_c);}
private:
    int m_c;
};
 
void main()
{
    A a;
    B *pb = (B*)(&a);
    pb->fun();
}
//程序的输出结果为1。

上面程序,对象在访问类成员时,编译器并没有存储该对象各个成员的实际地址,而是存储了其相对于当前对象首地址的偏移量,由于B类只有一个成员m_c,在编译阶段,编译器就记录了m_c对于B类对象的偏移量为0,故访问m_c时,便是访问当前对象地址this+偏移量0,注意,this在这里绑定的是A类对象的首地址,在A类中,偏移量为0的成员是m_a,故打印出m_a的值。

关于类成员偏移量的输出,可以用程序验证。

例如如下程序:将地址0强制转换为A类对象的地址,那么打印类成员m_a和m_b的地址便是他们的偏移量,如下分别输出0, 4。

cout<<&((A*)0)->m_a<<endl;
cout<<&((A*)0)->m_b<<endl;

再如,我们可以通过输出类成员指针来验证。

printf("%p\n",&A::m_a);
printf("%p\n",&A::m_b);

分别输出 00000000,00000004。
转自: https://b
log.csdn.net/yyc1023/article/details/20081381

#  if defined(MY_LIB)
#    define MY_EXPORT __declspec(dllexport)
#  else
#    define MY_EXPORT __declspec(dllimport)
#  endif
class MY_LIB A
{
public:
    A() {}
    ~A() {}
#ifdef MYMACRO
    int m_a = 1;
    int m_b = 2;
 #endif
};
///
class AEx :public A
{
public:
    AEx () {}
    ~AEx () {}
    void fun() {printf("%d %d", m_c);}
    int m_c = 3;
};
 

添加预处理宏MYMACRO编译A类所在的动态库工程,如果 B类所在的工程中未添加MYMACRO宏定义时,程序的输出结果为1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值