首页 > 试题广场 >

观察下面一段代码: class ClassA { publi

[不定项选择题]
观察下面一段代码:
class ClassA
{
public:
    virtual ~ ClassA() {};
    virtual void FunctionA() {};
};
class ClassB
{
public:
    virtual void FunctionB() {};
};
class ClassC : public ClassA,public ClassB
{
public:
};
ClassC aObject;
ClassA* pA=&aObject;
ClassB* pB=&aObject;
ClassC* pC=&aObject;
关于pA,pB,pC的取值,下面的描述中正确的是:
  • pA,pB,pC的取值相同
  • pC=pA+pB
  • pA和pB不相同
  • pC不等于pA也不等于pB
  • pC和pA相同
可以去翻翻 Inside the C++ object model 
发表于 2020-03-14 17:25:47 回复(0)
答案是C和E,先说结论,这种情况下,派生类的指针和第一个基类的指针应该是一样的,和第二个基类是不一样的。
pB和pA的差值是虚表指针的大小,32位机器是4字节,64位机器就是8字节了。
虚表的含义:
在C++中,每个有虚函数的类或者虚继承的子类,编译器都会为它生成一个虚表,表中的每一个元素都指向一个虚函数的地址
此外,编译器会为包含虚函数的类加上一个成员变量,是一个指向该虚函数表的指针(常被称为vptr),每一个由此类别派生出来的类,都有这么一个vptr。也就是说,如果一个类含有虚表,则该类的所有对象都会含有一个虚表指针,并且该虚表指针指向同一个虚表
虚表的内容是依据类中的虚函数声明次序一一填入函数指针。派生类别会继承基础类别的虚表(以及所有其他可以继承的成员),当我们在派生类中改写虚函数时,虚表就受了影响;表中的元素所指的函数地址将不再是基类的函数地址,而是派生类的函数地址。
发表于 2019-08-21 11:10:45 回复(2)
解释一下:ClassC虚表指针有了两个,分别在在对象首地址偏移0和4字节,pA指向的是基类ClassA基类虚表指针,pB指向的是基类ClassB虚表指针,然后pC指向按继承顺序第一个继承的类虚表指针也就是pA,所以pC=pA,pB与他们不相等,
详细虚表继承板砖地址:https://blog.csdn.net/haoel/article/details/1948051
有图有真相:

发表于 2019-08-27 11:37:44 回复(5)
解析上面的牛友已经说了,看看结果吧:

发表于 2019-10-25 17:24:37 回复(0)
既然是c类定义的对象,由于c类是多继承于a和b,则它的对象所占空间就要考虑虚函数表中指针的指向。用表格来说明: a类虚指针在表格第一行,其指向FuncA;b类虚指针在表格第二行(64位机,对a地址偏移8),其指向FuncB。而c类没有偏移,即使c有虚函数也是追加到a(即表格第一行)的后面,因为是多继承。
发表于 2022-10-23 09:39:52 回复(0)
换言之,这里的pA/pB/pC是虚表地址vptr
发表于 2022-02-19 13:31:13 回复(0)
#include <iostream>
using namespace std;

class ClassA
{
public:
    virtual ~ClassA() {};
    virtual void FunctionA() {};
};
class ClassB
{
public:
    virtual void FunctionB() {};
};
class ClassC : public ClassB, public ClassA
{
public:
};
ClassC aObject;
ClassA* pA = &aObject;
ClassB* pB = &aObject;
ClassC* pC = &aObject;

int main()
{
    cout << pA << ' ' << pB << ' ' << pC << endl;
}
pC先继承pB的话地址和pB是一样的。
发表于 2022-07-19 16:01:43 回复(0)
各位大佬,为啥PB指针会多偏移4个字节到B类的虚函数列表啊?
发表于 2021-05-03 10:31:49 回复(1)