- 一
#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。