I got that subobjects are member subobjects, base class subobjects and arrays. I couldn't find anything that explicit explain the two first terms. In the following code for example:
struct A{int a;};
struct B{int b;};
struct C:public A,public B{};
I think that: int a
is a member subobject of a possible, not yet instantiated, object of type A; int a
is a base class subobject of a possible, not yet instantiated, object of type C. Is it Right? What is the definition of member subobject and base class subobject? Could you provide examples?
CodePudding user response:
In your code, the base class subobjects of instances of C
are the instances of A
and B
contained inside it. Each of those subobjects has a subobject itself (a
and b
); those are not considered subobjects of the instance of C
(because they're subobjects of subobjects), but are considered "nested objects" of the instance of C
.
CodePudding user response:
Whenever a class inherits from another one it inherits, too, an instance of that class:
class A { };
class B : A { };
Then class B internally looks like:
class B
{
A a; // <- implicit base class sub-object, not visible to you
};
Note that in some cases there might be even be more than one A!
class A { };
class B : A { };
class C : A { };
class D : C, B { };
D then internally looks like:
class D
{
B b; // { A a; }
C c; // { A a; }
};
with b
and c
being the base class sub-objects; or in a flattened representation:
class D
{
A aFromB; // inherited from B, but not a sub-object of D itself
// other members of B
A aFromC; // inherited from C, again not a sub-object of D
// other members of C
};
B
and C
base class sub-objects are not visible in this representation, still they are there in form of the respective A
instance combined with the respective other members (think of having braces around).
If you want to avoid duplicates of A
, you need to inherit virtually: class B : virtual A { }
– all virtually inherited (directly or indirectly) instances of A
are then combined into one single instance (though if there are non-virtually inherited ones these remain in parallel to the combined one), consider:
class A { };
class B : A { };
class C : virtual A { };
class D : virtual A { };
class E : A, B, C
{
A combinedAFromCAndD;
// other members of B
// other members of C
A separateAFromD
// other members of D
};
Note: These layouts above are just examples, concrete layouts might vary.