Diamond shaped polymorphic Inheritance: sizeof Most derived Class
I understand that the Diamond shaped inheritance causes ambiguity and it can be avoided by using inheritance through virtual Base Classes
, the question is not about it. The question is about sizeof the most derived class in a diamond shaped hierarchy when the classes are polymorphic. Here is a sample code and the sample output:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void doSomething(){}
};
class Derived1:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived2:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived3:public Derived1,public Derived2
{
public:
virtual void doSomething(){}
};
int main()
{
Base obj;
Derived1 objDerived1;
Derived2 objDerived2;
Derived3 objDerived3;
cout<<"n Size of Base: "<<sizeof(obj);
cout<<"n Size of Derived1: "<<sizeof(objDerived1);
cout<<"n Size of Derived2: "<<sizeof(objDerived2);
cout<<"n Size of Derived3: "<<sizeof(objDerived3);
return 0;
}
The output i get is:
Size of Base: 4
Size of Derived1: 4
Size of Derived2: 4
Size of Derived3: 8
As I understand Base
contains a virtual member function and hence,
sizeof Base = size of vptr = 4 on this environment
Similar is the case Derived1
& Derived2
classes.
Here are my questions related to above scenario:
How about size of a Derived3
class object, Does it mean Derived3 class has 2 vptr?
How does the Derived3
class work with these 2 vptr, Any ideas about the mechanism it uses?
The sizeof classes is left as implementation detail of compiler & not defined by the Standard(as the virtual mechanism itself is an implementation detail of compilers)?
c++ sizeof virtual-inheritance diamond-problem memory-layout
add a comment |
I understand that the Diamond shaped inheritance causes ambiguity and it can be avoided by using inheritance through virtual Base Classes
, the question is not about it. The question is about sizeof the most derived class in a diamond shaped hierarchy when the classes are polymorphic. Here is a sample code and the sample output:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void doSomething(){}
};
class Derived1:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived2:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived3:public Derived1,public Derived2
{
public:
virtual void doSomething(){}
};
int main()
{
Base obj;
Derived1 objDerived1;
Derived2 objDerived2;
Derived3 objDerived3;
cout<<"n Size of Base: "<<sizeof(obj);
cout<<"n Size of Derived1: "<<sizeof(objDerived1);
cout<<"n Size of Derived2: "<<sizeof(objDerived2);
cout<<"n Size of Derived3: "<<sizeof(objDerived3);
return 0;
}
The output i get is:
Size of Base: 4
Size of Derived1: 4
Size of Derived2: 4
Size of Derived3: 8
As I understand Base
contains a virtual member function and hence,
sizeof Base = size of vptr = 4 on this environment
Similar is the case Derived1
& Derived2
classes.
Here are my questions related to above scenario:
How about size of a Derived3
class object, Does it mean Derived3 class has 2 vptr?
How does the Derived3
class work with these 2 vptr, Any ideas about the mechanism it uses?
The sizeof classes is left as implementation detail of compiler & not defined by the Standard(as the virtual mechanism itself is an implementation detail of compilers)?
c++ sizeof virtual-inheritance diamond-problem memory-layout
1
regarding the Standard question. Yes the mechanism of how to implement virtual methods is an implementation details and not specified. Yes the actual result ofsizeof
is an implementation details too, it notably depends on pointer size, if you were on a 64 bits platform, you would be seeing8/8/8/16
.
– Matthieu M.
Mar 31 '11 at 18:12
add a comment |
I understand that the Diamond shaped inheritance causes ambiguity and it can be avoided by using inheritance through virtual Base Classes
, the question is not about it. The question is about sizeof the most derived class in a diamond shaped hierarchy when the classes are polymorphic. Here is a sample code and the sample output:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void doSomething(){}
};
class Derived1:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived2:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived3:public Derived1,public Derived2
{
public:
virtual void doSomething(){}
};
int main()
{
Base obj;
Derived1 objDerived1;
Derived2 objDerived2;
Derived3 objDerived3;
cout<<"n Size of Base: "<<sizeof(obj);
cout<<"n Size of Derived1: "<<sizeof(objDerived1);
cout<<"n Size of Derived2: "<<sizeof(objDerived2);
cout<<"n Size of Derived3: "<<sizeof(objDerived3);
return 0;
}
The output i get is:
Size of Base: 4
Size of Derived1: 4
Size of Derived2: 4
Size of Derived3: 8
As I understand Base
contains a virtual member function and hence,
sizeof Base = size of vptr = 4 on this environment
Similar is the case Derived1
& Derived2
classes.
Here are my questions related to above scenario:
How about size of a Derived3
class object, Does it mean Derived3 class has 2 vptr?
How does the Derived3
class work with these 2 vptr, Any ideas about the mechanism it uses?
The sizeof classes is left as implementation detail of compiler & not defined by the Standard(as the virtual mechanism itself is an implementation detail of compilers)?
c++ sizeof virtual-inheritance diamond-problem memory-layout
I understand that the Diamond shaped inheritance causes ambiguity and it can be avoided by using inheritance through virtual Base Classes
, the question is not about it. The question is about sizeof the most derived class in a diamond shaped hierarchy when the classes are polymorphic. Here is a sample code and the sample output:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void doSomething(){}
};
class Derived1:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived2:public virtual Base
{
public:
virtual void doSomething(){}
};
class Derived3:public Derived1,public Derived2
{
public:
virtual void doSomething(){}
};
int main()
{
Base obj;
Derived1 objDerived1;
Derived2 objDerived2;
Derived3 objDerived3;
cout<<"n Size of Base: "<<sizeof(obj);
cout<<"n Size of Derived1: "<<sizeof(objDerived1);
cout<<"n Size of Derived2: "<<sizeof(objDerived2);
cout<<"n Size of Derived3: "<<sizeof(objDerived3);
return 0;
}
The output i get is:
Size of Base: 4
Size of Derived1: 4
Size of Derived2: 4
Size of Derived3: 8
As I understand Base
contains a virtual member function and hence,
sizeof Base = size of vptr = 4 on this environment
Similar is the case Derived1
& Derived2
classes.
Here are my questions related to above scenario:
How about size of a Derived3
class object, Does it mean Derived3 class has 2 vptr?
How does the Derived3
class work with these 2 vptr, Any ideas about the mechanism it uses?
The sizeof classes is left as implementation detail of compiler & not defined by the Standard(as the virtual mechanism itself is an implementation detail of compilers)?
c++ sizeof virtual-inheritance diamond-problem memory-layout
c++ sizeof virtual-inheritance diamond-problem memory-layout
edited Dec 7 '15 at 21:38
curiousguy
4,51222943
4,51222943
asked Mar 31 '11 at 16:17
Alok SaveAlok Save
164k35340482
164k35340482
1
regarding the Standard question. Yes the mechanism of how to implement virtual methods is an implementation details and not specified. Yes the actual result ofsizeof
is an implementation details too, it notably depends on pointer size, if you were on a 64 bits platform, you would be seeing8/8/8/16
.
– Matthieu M.
Mar 31 '11 at 18:12
add a comment |
1
regarding the Standard question. Yes the mechanism of how to implement virtual methods is an implementation details and not specified. Yes the actual result ofsizeof
is an implementation details too, it notably depends on pointer size, if you were on a 64 bits platform, you would be seeing8/8/8/16
.
– Matthieu M.
Mar 31 '11 at 18:12
1
1
regarding the Standard question. Yes the mechanism of how to implement virtual methods is an implementation details and not specified. Yes the actual result of
sizeof
is an implementation details too, it notably depends on pointer size, if you were on a 64 bits platform, you would be seeing 8/8/8/16
.– Matthieu M.
Mar 31 '11 at 18:12
regarding the Standard question. Yes the mechanism of how to implement virtual methods is an implementation details and not specified. Yes the actual result of
sizeof
is an implementation details too, it notably depends on pointer size, if you were on a 64 bits platform, you would be seeing 8/8/8/16
.– Matthieu M.
Mar 31 '11 at 18:12
add a comment |
4 Answers
4
active
oldest
votes
Yes, Derived3
has two vtable pointers. If you're accessing it by value, it uses the Derived3
version, or picks a function from a parent, or denotes that it's ambiguous if it can't decide.
In the case of a child, it uses the vtable corresponding to the parent 1/2 that's being used polymorphically.
Note that you didn't use virtual inheritance correctly: I believe Derived1 and 2 should inherit virtually from Base
. sizeof(Derived3)
still seems to be 8, because it still has two possible parents that could be treated as a Derived3
. When you cast up to one of the parents the compiler will actually adjust the object pointer to have the correct vtable.
Also I should point out that anything vtable-related is implementation specific because there isn't even any mention of vtables in the standard.
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
add a comment |
A small fix to your code: the virtual is supposed to be in the definition of derived2 and derived 3 in order to work.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
add a comment |
I think you are wondering about something that is totally implementation specific.
You should not assume anything about the size of the classes.
Edit: though being curious is a proven quality ;-)
add a comment |
Consider a slightly different case:
struct B { virtual void f(); };
struct L : virtual B { virtual void g(); };
struct R : virtual B { virtual void h(); };
struct D : L, R {};
In a typical implementation, L::g will be in the same position (say at
index 0) in L's vtable as R:h in R's vtable. Now consider what happens
given the following code:
D* pd = new D;
L* pl = pd;
R* pr = pd;
pl->g();
pr->h();
In the last two lines, the compiler will generate code to find the
address of the function at the same position in the vtable. So the
vtable accessed through pl cannot be the same as the one (or a prefix of
the one) accessed through pr. Thus, the complete object needs at least
two vptr, to point to two different vtable.
actually in typical implementationf
would probably come beforeg
orh
in the virtual table, so that no adjustement is necessary when usingL
orR
polymorphically as aB
(that is the layout of theL
table will be a superset of the layout of theB
table, so that theB
view of it conforms toB
attempts).
– Matthieu M.
Mar 31 '11 at 18:11
1
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5502994%2fdiamond-shaped-polymorphic-inheritance-sizeof-most-derived-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
Yes, Derived3
has two vtable pointers. If you're accessing it by value, it uses the Derived3
version, or picks a function from a parent, or denotes that it's ambiguous if it can't decide.
In the case of a child, it uses the vtable corresponding to the parent 1/2 that's being used polymorphically.
Note that you didn't use virtual inheritance correctly: I believe Derived1 and 2 should inherit virtually from Base
. sizeof(Derived3)
still seems to be 8, because it still has two possible parents that could be treated as a Derived3
. When you cast up to one of the parents the compiler will actually adjust the object pointer to have the correct vtable.
Also I should point out that anything vtable-related is implementation specific because there isn't even any mention of vtables in the standard.
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
add a comment |
Yes, Derived3
has two vtable pointers. If you're accessing it by value, it uses the Derived3
version, or picks a function from a parent, or denotes that it's ambiguous if it can't decide.
In the case of a child, it uses the vtable corresponding to the parent 1/2 that's being used polymorphically.
Note that you didn't use virtual inheritance correctly: I believe Derived1 and 2 should inherit virtually from Base
. sizeof(Derived3)
still seems to be 8, because it still has two possible parents that could be treated as a Derived3
. When you cast up to one of the parents the compiler will actually adjust the object pointer to have the correct vtable.
Also I should point out that anything vtable-related is implementation specific because there isn't even any mention of vtables in the standard.
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
add a comment |
Yes, Derived3
has two vtable pointers. If you're accessing it by value, it uses the Derived3
version, or picks a function from a parent, or denotes that it's ambiguous if it can't decide.
In the case of a child, it uses the vtable corresponding to the parent 1/2 that's being used polymorphically.
Note that you didn't use virtual inheritance correctly: I believe Derived1 and 2 should inherit virtually from Base
. sizeof(Derived3)
still seems to be 8, because it still has two possible parents that could be treated as a Derived3
. When you cast up to one of the parents the compiler will actually adjust the object pointer to have the correct vtable.
Also I should point out that anything vtable-related is implementation specific because there isn't even any mention of vtables in the standard.
Yes, Derived3
has two vtable pointers. If you're accessing it by value, it uses the Derived3
version, or picks a function from a parent, or denotes that it's ambiguous if it can't decide.
In the case of a child, it uses the vtable corresponding to the parent 1/2 that's being used polymorphically.
Note that you didn't use virtual inheritance correctly: I believe Derived1 and 2 should inherit virtually from Base
. sizeof(Derived3)
still seems to be 8, because it still has two possible parents that could be treated as a Derived3
. When you cast up to one of the parents the compiler will actually adjust the object pointer to have the correct vtable.
Also I should point out that anything vtable-related is implementation specific because there isn't even any mention of vtables in the standard.
answered Mar 31 '11 at 16:23
Mark BMark B
85.2k583164
85.2k583164
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
add a comment |
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
Thanks, I corrected the typo of the Derived1 & Derived2 virtually inheriting from Base. The O/P is still the same.
– Alok Save
Mar 31 '11 at 16:32
add a comment |
A small fix to your code: the virtual is supposed to be in the definition of derived2 and derived 3 in order to work.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
add a comment |
A small fix to your code: the virtual is supposed to be in the definition of derived2 and derived 3 in order to work.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
add a comment |
A small fix to your code: the virtual is supposed to be in the definition of derived2 and derived 3 in order to work.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9
A small fix to your code: the virtual is supposed to be in the definition of derived2 and derived 3 in order to work.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.9
answered Mar 31 '11 at 16:24
ManicQinManicQin
11418
11418
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
add a comment |
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
Thanks I corrected the typo
– Alok Save
Mar 31 '11 at 16:39
add a comment |
I think you are wondering about something that is totally implementation specific.
You should not assume anything about the size of the classes.
Edit: though being curious is a proven quality ;-)
add a comment |
I think you are wondering about something that is totally implementation specific.
You should not assume anything about the size of the classes.
Edit: though being curious is a proven quality ;-)
add a comment |
I think you are wondering about something that is totally implementation specific.
You should not assume anything about the size of the classes.
Edit: though being curious is a proven quality ;-)
I think you are wondering about something that is totally implementation specific.
You should not assume anything about the size of the classes.
Edit: though being curious is a proven quality ;-)
answered Mar 31 '11 at 16:23
Stephane RollandStephane Rolland
19.1k2698146
19.1k2698146
add a comment |
add a comment |
Consider a slightly different case:
struct B { virtual void f(); };
struct L : virtual B { virtual void g(); };
struct R : virtual B { virtual void h(); };
struct D : L, R {};
In a typical implementation, L::g will be in the same position (say at
index 0) in L's vtable as R:h in R's vtable. Now consider what happens
given the following code:
D* pd = new D;
L* pl = pd;
R* pr = pd;
pl->g();
pr->h();
In the last two lines, the compiler will generate code to find the
address of the function at the same position in the vtable. So the
vtable accessed through pl cannot be the same as the one (or a prefix of
the one) accessed through pr. Thus, the complete object needs at least
two vptr, to point to two different vtable.
actually in typical implementationf
would probably come beforeg
orh
in the virtual table, so that no adjustement is necessary when usingL
orR
polymorphically as aB
(that is the layout of theL
table will be a superset of the layout of theB
table, so that theB
view of it conforms toB
attempts).
– Matthieu M.
Mar 31 '11 at 18:11
1
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
add a comment |
Consider a slightly different case:
struct B { virtual void f(); };
struct L : virtual B { virtual void g(); };
struct R : virtual B { virtual void h(); };
struct D : L, R {};
In a typical implementation, L::g will be in the same position (say at
index 0) in L's vtable as R:h in R's vtable. Now consider what happens
given the following code:
D* pd = new D;
L* pl = pd;
R* pr = pd;
pl->g();
pr->h();
In the last two lines, the compiler will generate code to find the
address of the function at the same position in the vtable. So the
vtable accessed through pl cannot be the same as the one (or a prefix of
the one) accessed through pr. Thus, the complete object needs at least
two vptr, to point to two different vtable.
actually in typical implementationf
would probably come beforeg
orh
in the virtual table, so that no adjustement is necessary when usingL
orR
polymorphically as aB
(that is the layout of theL
table will be a superset of the layout of theB
table, so that theB
view of it conforms toB
attempts).
– Matthieu M.
Mar 31 '11 at 18:11
1
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
add a comment |
Consider a slightly different case:
struct B { virtual void f(); };
struct L : virtual B { virtual void g(); };
struct R : virtual B { virtual void h(); };
struct D : L, R {};
In a typical implementation, L::g will be in the same position (say at
index 0) in L's vtable as R:h in R's vtable. Now consider what happens
given the following code:
D* pd = new D;
L* pl = pd;
R* pr = pd;
pl->g();
pr->h();
In the last two lines, the compiler will generate code to find the
address of the function at the same position in the vtable. So the
vtable accessed through pl cannot be the same as the one (or a prefix of
the one) accessed through pr. Thus, the complete object needs at least
two vptr, to point to two different vtable.
Consider a slightly different case:
struct B { virtual void f(); };
struct L : virtual B { virtual void g(); };
struct R : virtual B { virtual void h(); };
struct D : L, R {};
In a typical implementation, L::g will be in the same position (say at
index 0) in L's vtable as R:h in R's vtable. Now consider what happens
given the following code:
D* pd = new D;
L* pl = pd;
R* pr = pd;
pl->g();
pr->h();
In the last two lines, the compiler will generate code to find the
address of the function at the same position in the vtable. So the
vtable accessed through pl cannot be the same as the one (or a prefix of
the one) accessed through pr. Thus, the complete object needs at least
two vptr, to point to two different vtable.
answered Mar 31 '11 at 17:09
James KanzeJames Kanze
129k9137278
129k9137278
actually in typical implementationf
would probably come beforeg
orh
in the virtual table, so that no adjustement is necessary when usingL
orR
polymorphically as aB
(that is the layout of theL
table will be a superset of the layout of theB
table, so that theB
view of it conforms toB
attempts).
– Matthieu M.
Mar 31 '11 at 18:11
1
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
add a comment |
actually in typical implementationf
would probably come beforeg
orh
in the virtual table, so that no adjustement is necessary when usingL
orR
polymorphically as aB
(that is the layout of theL
table will be a superset of the layout of theB
table, so that theB
view of it conforms toB
attempts).
– Matthieu M.
Mar 31 '11 at 18:11
1
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
actually in typical implementation
f
would probably come before g
or h
in the virtual table, so that no adjustement is necessary when using L
or R
polymorphically as a B
(that is the layout of the L
table will be a superset of the layout of the B
table, so that the B
view of it conforms to B
attempts).– Matthieu M.
Mar 31 '11 at 18:11
actually in typical implementation
f
would probably come before g
or h
in the virtual table, so that no adjustement is necessary when using L
or R
polymorphically as a B
(that is the layout of the L
table will be a superset of the layout of the B
table, so that the B
view of it conforms to B
attempts).– Matthieu M.
Mar 31 '11 at 18:11
1
1
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
@Matthieu M. Yes. In a lot of implementations, the vtable will start with one or more special pointers, to type_info information, for example, followed by the virtual functions in the base classes, in order, then the virtual functions of the class which aren't overrides of a base. The fact remains, however, that the vtable for L will have g in the same place as the vtable for R has h, so the same vtable cannot be used for both L and R in D.
– James Kanze
Apr 1 '11 at 7:51
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
exact, in a lot of implementations. Building smarter vtables require whole program analysis / link-time optimization.
– Matthieu M.
Apr 1 '11 at 12:23
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
Thats a interesting/convincing explanation.Thanks!
– Alok Save
Apr 4 '11 at 6:07
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
@MatthieuM. "the layout of the L table will be a superset" The invariants of the L table will be...
– curiousguy
Nov 19 '18 at 21:19
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5502994%2fdiamond-shaped-polymorphic-inheritance-sizeof-most-derived-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
regarding the Standard question. Yes the mechanism of how to implement virtual methods is an implementation details and not specified. Yes the actual result of
sizeof
is an implementation details too, it notably depends on pointer size, if you were on a 64 bits platform, you would be seeing8/8/8/16
.– Matthieu M.
Mar 31 '11 at 18:12