您的位置:首页 > 其它

空类大小及指针转换(多继承)

2018-03-02 16:38 204 查看
先得出结论:
1. 空类大小为1(仅标识类的存在),如果空类中加了virtual关键字则是4(虚函数表指针)。
2. 子类指针转父类时, 强转、static_cast、dynamic_cast效果一样!
3. 强转时,A,B 指针值 与 C的指针值可能相同或不同!
4.虚函数原理,请查阅http://blog.csdn.net/hq354974212/article/details/76985270

情形一:class A
{
public:
void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
void AAA()
{
printf("C::AAA();\n");
}
void BBB()
{
printf("C::BBB();\n");
}
};此处C的大小并不是想象中的1+1=2,而是1,因为空类只需要占1字节即可!



这里A指针的地址与C指针地址一样!

情形二:
class A
{
public:
virtual void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
void AAA()
{
printf("C::AAA();\n");
}
void BBB()
{
printf("C::BBB();\n");
}
};此处C的大小并不是想象中的4(虚函数表指针)+1=5,而是4,因为C已经不为空类了!



这里A指针的地址与C指针地址一样!

情形三:class A
{
public:
void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
virtual void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
void AAA()
{
printf("C::AAA();\n");
}
void BBB()
{
printf("C::BBB();\n");
}
};
此处C的大小并不是想象中的4(虚函数表指针)+1=5,而是4,因为C已经不为空类了!  



这里B指针的地址与C指针地址一样!

情形四:
class A
{
public:
virtual void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
virtual void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
void AAA()
{
printf("C::AAA();\n");
}
void BBB()
{
printf("C::BBB();\n");
}
};此处C的大小是8(A虚表指针,B虚表指针)



这里A指针的地址与C指针地址一样!

情形五:
class A
{
public:
void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
virtual void AAA()
{
printf("C::AAA();\n");
}
void BBB()
{
printf("C::BBB();\n");
}
};此处C的大小是4(C虚表指针)+1+1,字节对齐后为8!



这里A指针,B指针的地址都与C指针地址不一样!

情形六:
class A
{
public:
void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
void AAA()
{
printf("C::AAA();\n");
}
virtual void BBB()
{
printf("C::BBB();\n");
}
};此处C的大小是4(C虚表指针)+1+1,字节对齐后为8!



这里A指针,B指针的地址都与C指针地址不一样!

情形七:
class A
{
public:
void AAA() { printf("A::AAA();\n"); }
};

class B
{
public:
void BBB() { printf("B::BBB();\n"); };
};

class C :public A, public B
{
public:
virtual void AAA()
{
printf("C::AAA();\n");
}
virtual void BBB()
{
printf("C::BBB();\n");
}
};此处C的大小是4(C虚表指针)+1+1,字节对齐后为8!



这里A指针,B指针的地址都与C指针地址不一样!

以上七种情形用同一份测试代码:int main()
{

C c;
printf("三个类的大小:C:%d A:%d B:%d \n", sizeof(C) ,sizeof(A),sizeof(B));
printf("子类指针地址:%p\n",&c);

A *pA1 = ( A *)&c;
A *pA2 = static_cast< A *>(&c);
A *pA3 = dynamic_cast< A *>(&c);
printf("父类A指针地址:%p, %p, %p\n", pA1,pA2,pA3);
pA1->AAA();

B *pB1 = ( B *)&c;
B *pB2 = static_cast< B *>(&c);
B *pB3 = dynamic_cast< B *>(&c);
printf("父类B指针地址:%p, %p, %p\n", pB1, pB2, pB3);
pB1->BBB();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: