This question already has answers here:
How does virtual inheritance actually work?
(1 answer)
Internal mechanism of virtual inheritance
(1 answer)
How does virtual inheritance solve the "diamond" (multiple inheritance) ambiguity?
(5 answers)
How C++ virtual inheritance is implemented in compilers?
(5 answers)
Closed 11 months ago.
Consider the following code:-
#include<iostream>
using namespace std;
class A
{
public:
int a;
A()
{
a = 10;
cout<<"Address of a in A "<<&a<<endl;
}
};
class B : public virtual A {
public:
B()
{
cout<<"Address of a in B "<<&a<<endl;
}
};
class C : public virtual A {
public:
C()
{
cout<<"Address of a in C "<<&a<<endl;
}
};
class D : public B, public C {
public:
D()
{
cout<<"Address of a in D "<<&a<<endl;
}
};
int main()
{
A a;
B b;
C c;
D d;
return 0;
}
So, here when we create an object of D class, Constructors are called in this order A()->B()->C()->D().
Here A() is not called again before C() because we had made use of virtual keyword, which is preventing the constructor A() to be called again.
** Question: 1 But, I wanted to know what is happening in background in code when we are using the virtual keyword?
Question 2 And is variable a in class A and class B point to same memory location?
Question 3 And why this variable's memroy address differs in class C when A is not made virtual from the address of that variable in B?**
Related
This question already has answers here:
Why doesn't polymorphism work without pointers/references?
(6 answers)
What is object slicing?
(18 answers)
Closed 3 months ago.
I am trying to understand why static_cast works different when it is performed on object than when it is performed on a pointer to object.
class A
{
int myA;
public:
A() { myA = 11; };
virtual void Do() { printf("\n A class is executed "); }
};
class B : public A
{
int myB;
public:
B(){ myB = 22; }
void Do() { printf("\n B class is executed "); }
};
When the following cast is performed, A::Do() is executed. Why?
Why B's virtual table is neglected?
A t_a;
B t_b;
(static_cast<A>(t_b)).Do(); //output: A class is executed
But when it is done via pointer, B::Do() is executed.
A* pA = new B;
pA->Do();
(static_cast<A*>(pA))->Do(); //output: B class is executed
Can you give me a full explanation (including memory layout) to understand the difference.
This question already has answers here:
Double inheritance of enable_shared_from_this
(3 answers)
Closed 2 years ago.
When I try to run this code I get bad_weak_ptr exception:
using namespace std;
class O {
public:
O() {}
};
class A : public std::enable_shared_from_this<A>, virtual public O {
public:
A() {}
};
class B : public std::enable_shared_from_this<B>, virtual public O {
public:
B() {}
void GetShared() {
shared_from_this();
}
};
class C : public A, public B {
public:
C() {}
};
int main()
{
std::shared_ptr<B> pt = std::make_shared<C>();
pt->GetShared();
}
I would like to create instance of C class but then return B shared_ptr because that is what other interface requires. Is there a way to fix this code ? I cannot seem to do that.
Well as far as I know you are trying to do the undoable:
Inheritance in C++ means that you also include the same members of the parent classes. However for class C that would mean 2 classes that are already supposed to be held by a std::shared_ptr. But by the inheritance you tell the compiler that C should contain sub instances of A and B not held by a std::shared_ptr. shared_from_this will complain about this fact at run time by a bad weak ptr exception.
Probably you want C to be held only by a std::shared_ptr, then you can to the attached code.
If you simply want to "up-cast" a instance of C i.e. use it as it would be a class of B you can simply use a B& or use std::shared_ptr with out std::enables_shared_from_this or only on the up most class.
#include <memory>
using namespace std;
class O {
public:
O() {}
};
struct A : virtual public O {
};
struct B : virtual O {
B() {}
void GetShared() {
}
};
struct C : std::enable_shared_from_this<C>, A, B {
C() = default;
};
int main()
{
std::shared_ptr<B> pt = std::make_shared<C>();
pt->GetShared();
}
This question already has answers here:
Virtual Inheritance: Error: no unique final overrider
(2 answers)
Multiple (diamond) inheritance compiles without "virtual", but doesn't with
(2 answers)
Closed 6 years ago.
I have this part of code
#include <iostream>
using namespace std;
class A {
public:
int i;
A(){i = 0; }
virtual void f() { cout << i; }
};
class B1 : virtual public A {
public:
B1() { f(); }
void f() { cout << i+10; }
};
class B2 : virtual public A {
public:
B2() { f(); }
void f() { cout << i+1; }
};
class C : public B1, public B2 {
public:
C() {}
};
void main(){
C c;
//c.A::f();
}
First, I understand the main idea behind using virtual inheritance (diamond) in order to create only one A object in memory.
In this example, I get compilation error in C class:
override of virtual function "A::f" is ambiguous
If I remove the virtual inheritance. The code compiles, there is no error in class C as before.
If I remove the comment from the last code line it still compiles. I understand that in this case the f() function that will be executed is the one from the first class that C inherits from.
Now, if I replace c.A::f() with c.f() I get a compilation error at this specific line.
Can someone please explain this behaviour and the differences between these cases?
The problem is with C not with your expression call. As f is virtual and redefined twice in B1 and B2 then the C class is malformed because a call to fwould be ambiguous (which override to choose?). Add an override of f in Cand everything will be ok.
Within the class C you must choose which variant of f to usr. That is, using B1::f; or using B2::f.
This question already has answers here:
C++ virtual function from constructor [duplicate]
(7 answers)
Closed 7 years ago.
There is a c++ program:
# include <iostream>
using namespace std;
class base
{
public:
base()
{
cout<<"base"<<endl;
f();
}
virtual void f() {
cout<<"base f"<<endl;
}
};
class derive: public base
{
public:
derive()
{
cout<<"derive"<<endl;
f();
}
void f() {
cout<<"derive f"<<endl;
}
};
int main()
{
derive d;
return 1;
}
and it outputs:
base
base f
derive
derive f
I am wondering why base f appears?
I quess in base the constrctor expands to:
cout<<"base"<<endl;
this.f();
But this should point to derive so why base f is print out?
During construction, in the baseclass constructor, the actual type of the object is base, even though it lateron continues to become a derived. The same happens during destruction, btw, and you can also verify the type using typeid.
This question already has answers here:
c++ virtual inheritance
(3 answers)
Closed 10 years ago.
The output of the program below is:
5
5
#include <iostream>
using namespace std;
struct A
{
public:
int myInt;
A(int n): myInt(n){}
A(): myInt(5) {}
};
class B : virtual public A
{
public:
B(int n):A(10) {}
B():A(10) {}
};
class C : virtual public A
{
public:
C(int n):A(3*n) {}
};
class D : public B, public C
{
public:
D(int n=90) : C(2*n), B(n) {}
};
class E : public D
{
public:
E(int n=20):D(n-1) {}
};
int main()
{
D d(100);
cout << d.myInt << endl;
E e;
cout << e.myInt << endl;
return 0;
}
Consider the object d. From what I understand the inheritance is constructed based on the order of the inheritance list (rather than the initialization list) so B class is constructed first with the param 100 which goes to class A with the parameter 10. So now A sets myInt to the value 10. The same goes for Class c and because myInt is virtual then it is set to the number 600. I never expected 5. why is this happening?
See article in parashift:
Because a virtual base class subobject occurs only once in an
instance, there are special rules to make sure the virtual base
class's constructor and destructor get called exactly once per
instance. The C++ rules say that virtual base classes are constructed
before all non-virtual base classes. The thing you as a programmer
need to know is this: constructors for virtual base classes anywhere
in your class's inheritance hierarchy are called by the "most derived"
class's constructor.