Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
一个g++;编译器用虚函数实现多重继承? 在“C++对象模型内部”中提到,派生类具有 n 1 < /COD>额外的虚拟表,即 n>代码>是基类的数目。我用g++编译器做了一些实验,我的机器是64位的。 下面是我的代码 class A{ private: int a; public: virtual void print() const{ cout << a << endl; } }; class B : A{ private: int b; public: virtual void set(int num){ b = num; } }; class C : public A, public B{ private: int c; public: void print() const{ cout << c << endl; } void set(int num){ c = num; } };_C++ - Fatal编程技术网

一个g++;编译器用虚函数实现多重继承? 在“C++对象模型内部”中提到,派生类具有 n 1 < /COD>额外的虚拟表,即 n>代码>是基类的数目。我用g++编译器做了一些实验,我的机器是64位的。 下面是我的代码 class A{ private: int a; public: virtual void print() const{ cout << a << endl; } }; class B : A{ private: int b; public: virtual void set(int num){ b = num; } }; class C : public A, public B{ private: int c; public: void print() const{ cout << c << endl; } void set(int num){ c = num; } };

一个g++;编译器用虚函数实现多重继承? 在“C++对象模型内部”中提到,派生类具有 n 1 < /COD>额外的虚拟表,即 n>代码>是基类的数目。我用g++编译器做了一些实验,我的机器是64位的。 下面是我的代码 class A{ private: int a; public: virtual void print() const{ cout << a << endl; } }; class B : A{ private: int b; public: virtual void set(int num){ b = num; } }; class C : public A, public B{ private: int c; public: void print() const{ cout << c << endl; } void set(int num){ c = num; } };,c++,C++,然后,我对以下问题感到困惑 甲级 尺寸=16对齐=8 底座尺寸=12底座对齐=8 我不明白为什么A级的大小是16,基本大小和对齐是什么意思?我认为类A的大小应该是12个字节,vptr为8个字节,intA为4个字节。B类也一样 我原以为C类有2个vtables,但结果显示只有一个有7个条目。这个vtable和C类的两个vptr之间有什么关系 最后一行显示vptr=(&C::ZTV1C)+48u),48是什么意思?C类的vtable的最后一个条目显示 48(int(*)(…)C::\uzthn1

然后,我对以下问题感到困惑

  • 
    甲级
    尺寸=16对齐=8
    底座尺寸=12底座对齐=8
    
    我不明白为什么A级的大小是16,基本大小和对齐是什么意思?我认为类A的大小应该是12个字节,
    vptr
    为8个字节,
    intA
    为4个字节。B类也一样
  • 我原以为C类有2个
    vtables
    ,但结果显示只有一个有7个条目。这个
    vtable
    和C类的两个
    vptr
    之间有什么关系
  • 最后一行显示
    vptr=(&C::ZTV1C)+48u)
    ,48是什么意思?C类的
    vtable
    的最后一个条目显示
    48(int(*)(…)C::\uzthn16\un1c3setei
    这是什么意思?它不是虚拟函数的名称和到顶部的偏移量。为什么第二个
    vptr
    指向此条目
  • 这是有关。对于多重继承,一个对象可能有几个继承(可能每个包含虚拟成员函数的超类有一个继承)


    将对象指针强制转换为某些父类可能需要添加一些偏移量(以获得正确的vtable和member函数)。

    关于问题1,您需要查看结构填充。您的PC arch是16字节对齐的。int需要4个字节,print的函数指针需要8个字节,因此12个字节表示基本大小,最后4个字节用于数据对齐。()
    (gdb) p a
    $1 = (A) {
      _vptr.A = 0x400bb0 <vtable for A+16>, 
      a = 0
    }
    (gdb) p b
    $2 = (B) {
      _vptr.B = 0x400b90 <vtable for B+16>, 
      b = 4196384
    }
    (gdb) p c
    $3 = (C) {
      <A> = {
        _vptr.A = 0x400b50 <vtable for C+16>, 
        a = 4197101
      }, 
      <B> = {
        _vptr.B = 0x400b70 <vtable for C+48>, 
        b = 0
      }, 
      members of C: 
      c = 0
    }
    
     Vtable for A
        A::_ZTV1A: 3u entries
        0     (int (*)(...))0
        8     (int (*)(...))(& _ZTI1A)
        16    (int (*)(...))A::print
    
        Class A
           size=16 align=8
           base size=12 base align=8
        A (0x0x7fe4654956c0) 0
            vptr=((& A::_ZTV1A) + 16u)
    
        Vtable for B
        B::_ZTV1B: 3u entries
        0     (int (*)(...))0
        8     (int (*)(...))(& _ZTI1B)
        16    (int (*)(...))B::set
    
        Class B
           size=16 align=8
           base size=12 base align=8
        B (0x0x7fe465495720) 0
            vptr=((& B::_ZTV1B) + 16u)
    
        Vtable for C
        C::_ZTV1C: 7u entries
        0     (int (*)(...))0
        8     (int (*)(...))(& _ZTI1C)
        16    (int (*)(...))C::print
        24    (int (*)(...))C::set
        32    (int (*)(...))-16
        40    (int (*)(...))(& _ZTI1C)
        48    (int (*)(...))C::_ZThn16_N1C3setEi
    
        Class C
           size=32 align=8
           base size=32 base align=8
        C (0x0x7fe46516e690) 0
            vptr=((& C::_ZTV1C) + 16u)
          A (0x0x7fe465495780) 0
              primary-for C (0x0x7fe46516e690)
          B (0x0x7fe4654957e0) 16
              vptr=((& C::_ZTV1C) + 48u)