获取的sizeof对象的成员(Get the sizeof Object's Members

2019-10-23 21:00发布

有一个目标是谁的会员我需要找到的大小。 我特别询问对象的大小,而不是考虑v表。 此外,我不能修改它,所以我不能趁这个答案 。

有没有在C ++这个规定,超越总结硬编码sizeof每个成员?

据我所知,V-表不是用C ++授权。 我也知道什么是我做这个信息将被广泛认为是“坏的形式”。 这个问题很简单询问,如果有可能,不认可的行为。


它已经到了我的注意,我需要澄清这个问题 。 我想了解这个问题是怎么投父到子。 也就是说,我希望保留孩子的v表,但复制母公司的成员变量: https://stackoverflow.com/a/31454039/2642059

接受的答案确实提供了我,我需要做到这一点的信息。 但是,在-尽管行为,我认为地方性的到最差的http://stackoverflow.com curiousguy 指出公认的答案的缺点 。

从接受的答案,多重继承的扩展显然是显而易见的,但它是有效的,答案应该包括它。 作为权宜之计我添加的如何处理多重继承一个活生生的例子: http://ideone.com/1QOrMz我会要求user2596732更新他的回答还是我会补充回答添加到如何处理的问题多重继承。

Answer 1:

为了发现多态对象的布局,你可以比较指针成员对象; 简单的演示程序“绘制”的符号的对象的布局:

  • 小写字母是数据成员的名称
  • 大写字母是一个基类的名称
  • *表示对象的一部分,该不属于任何构件子对象或基类子对象

存在用于每个字节一个符号(一个char是由定义一个字节)。

vptr的(一个或多个)必须在“空”的空间,而不是分配给数据成员的空间。

类型定义如下:

struct T { 
    virtual void foo();
    int i;
};

struct U { 
    virtual void bar();
    long long l;
};

struct Der : T, U { 
};

struct Der2 : virtual T, U { 
};

struct Der3 : virtual T, virtual U { 
};

输出是:

sizeof void* is 4
sizeof T is 8
sizeof i is 4
i is at offset 4
layout of T is 
****iiii
sizeof U is 12
sizeof U::l is 8
l is at offset 4
layout of U is 
****llllllll
sizeof Der is 20
Der::i is at offset 4
Der::l is at offset 12
Der::T is at offset 0
Der::U is at offset 8
layout of Der is 
TTTTiiiiUUUUllllllll
sizeof Der2 is 20
Der2::i is at offset 16
Der2::l is at offset 4
Der2::T is at offset 12
Der2::U is at offset 0
layout of Der2 is 
UUUUllllllllTTTTiiii
sizeof Der3 is 24
Der3::i is at offset 8
Der3::l is at offset 16
Der3::T is at offset 4
Der3::U is at offset 12
layout of Der3 is 
****TTTTiiiiUUUUllllllll

见https://ideone.com/g5SZwk

因为我们知道,编译器使用vptrs,该vptrs的位置是在这些“图”明显。

关于用C ++继承

非虚继承

当不使用虚拟继承,基类的子对象继承图总是植根于最派生类树,即使当子类型图是不是树:

struct Repeated {
    virtual void f();
    virtual void g();
};
struct Left : Repeated {
    void g();
};
struct Right : Repeated {
    void g();
};
struct Bottom : Left, Right {
    void f();
};

子类型图为:

           Left
         /      \
Repeated          Bottom
         \      /
           Right

子对象图是:

Left::Repeated ---  Left
                         \
                          Bottom
                         /
Right::Repeated --- Right

这是非虚拟继承的决定性影响。图表并不总是一致。 如果你不明白,你不明白非虚继承!

这意味着从转换Bottom*Repeated*不明确。

在这个例子:

  • Bottom::f()重载了Left::Repeated::f()Right::Repeated::f()在同一时间。
  • Left::Repeated::g()由重写Left::g()
  • Right::Repeated::g()被重写Right::g()

这里的名称查找gBottom会失败的不确定性,所以它是使用不合格的错误gBottom

虚拟继承

当使用虚拟继承,基类的子对象继承是最派生类作为唯一的终端的无环向图:

struct Unique { virtual void f(); };
struct Left : virtual Unique { void f(); };
struct Right : virtual Unique { void f(); };
struct Bottom : Left, Right { void f(); };

这里所有其他f()声明重写Unique::f()

这里的子对象图相匹配的亚型图:

           Left
         /      \
  Unique         Bottom
         \      /
           Right


Answer 2:

不。



Answer 3:

的sizeof(类)只包括一个虚函数表指针。

class A
{
public:
    int a = 2;
    int b = 2;
    virtual void x() {
    };

    virtual void y() {
    };
};


class B : public A
{
public:
    int c = 2;
    int d = 2;
    virtual void y() {
    };
};

class C : public A
{
public:
    int c = 2;
    int d = 2;
    int e = 2;
    virtual void x() {
    };
};

所以,在这个例子中,

    cout << sizeof(A)-sizeof(void*) << endl;
    cout << sizeof(B)-sizeof(void*) << endl;
    cout << sizeof(C)-sizeof(void*) << endl;

应该给你正确的答案。 8 16 20



文章来源: Get the sizeof Object's Members