This question already has answers here:
Object layout in case of virtual functions and multiple inheritance
(4 answers)
Closed 4 years ago.
I understand that for single inheritance a pointer to a virtual function table is added to determine what parent class functions to call at runtime.
class Genius {
int IQ;
public:
virtual void brag();
};
class Me : public Genius {
int age;
};
When instantiated, the memory layout of Me should look something like
pointer to Genius vtable
int iq
int age
But what happens in the case of multiple inheritance?
// Assume CoolDude has virtual functions as well
class Me : public Genius, public CoolDude {
int age;
};
What does the memory layout of the Me class look like now? How is multiple inheritance handled?
The class will have 2 pointers to vtables, one to its implementation of Genius and one to its implementation of CoolDude. When casting to a base class, the the returned pointer will differ from the original by the offset of the vtable(and other members) or the base class.
Related
This question already has answers here:
Get base class for a type in class hierarchy
(4 answers)
Closed 3 years ago.
Is there a trait that returns the base class of a specific class, with the assumption that there is no multiple inheritance involved? Basically something like:
struct Base
{
};
struct Derived : public Base
{
};
struct DerivedDerived : public Derived
{
};
static_assert(std::is_same_v<base<DerivedDerived>::type,Derived>);
static_assert(std::is_same_v<base<Derived>::type,Base>);
static_assert(std::is_same_v<base<Base>::type,Base>);
// with levels
static_assert(std::is_same_v<base<0,DerivedDerived>::type,Base>);
static_assert(std::is_same_v<base<1,DerivedDerived>::type,Derived>);
static_assert(std::is_same_v<base<2,DerivedDerived>::type,DerivedDerived>);
static_assert(std::is_same_v<base<0,Derived>::type,Base>);
static_assert(std::is_same_v<base<1,Derived>::type,Derived>);
Nope. You can test whether a given type inherits from a given other type with std::is_base_of, but not ask for the base type outright. That is, until C++ gets static reflection sometime in the future.
This question already has answers here:
What is a vtable in C++ [duplicate]
(3 answers)
Why do we need a virtual table?
(5 answers)
How are virtual functions and vtable implemented?
(12 answers)
Closed 5 years ago.
What is the use of vtable (or why is vtable required ) in case of virtual inheritance ? what does this vtable points to in this case.
example:
class A
{
void show()
{ }
};
class B : virtual A
{
void disp()
{ }
};
In the above example the size of class B is 8 bytes. which means class B has vptr pointing to a Vtable. What does this vtable point to .
A vtable is the most common way of implementing the virtual keyword in C++ -- any class that uses the virtual keyword will have a vtable created for it and every instance of that class will contain a pointer to that (single) vtable. The vtable contains information on the dynamic class of the object (to support dynamic_cast and typeinfo) as well as information as to where virtual base classes and functions of the class are located.
In this specific case, the vtable for B will likely contain just dynamic class info, as A has no data members or virtual functions.
This question already has answers here:
C++ abstract class without pure virtual functions?
(3 answers)
Closed 7 years ago.
I will start with what's most of us already know:
If I want my class to be abstract, I must define at least one of its methods as "pure virtual", for example, here, the method someFunction() is defined as "pure virtual", as it is defined with the virtual keyword and it is assigned with 0:
class SomeClass {
virtual void someFunction() = 0;
};
My question is, when I want an "abstract class", i.e. a class which cannot be instantiated (like "pure virtual" class), but I want to implement all its methods. Is there any standard way to do it?
My current workaround is ugly - I just define another dummy pure virtual method:
class UglyWorkaround {
public:
virtual void doAction1();
virtual void doAction2();
// My ugly workaround for making the class abstract - defining a dummy method
virtual void thisIsADummyMethod() = 0;
};
This is very bad, as any deriving non-abstract class will have to implement it
Is there a more standard/popular way to define and implement such a class?
I want to clarify - I don't want another ugly workaround - I ask whether there is any standard way that is commonly used. The objective is to make the code readable for other programmers, so they immediately understand that the class is abstract
Define the constructor protected
This question already has answers here:
Prefer composition over inheritance?
(35 answers)
Closed 8 years ago.
I'm quite new in C++ and I would like to learn good practices from the beginning, so my question explained with an example is:
Having:
class A
{
int mNumber;
};
If I need to use class A inside class B, what is better?to include an object?
class B
{
A * mpA;
int mColor;
};
Or inherit from Class A?
class B : public A
{
int mColor;
};
Is there any good habit talking in a generally way to do this?
Prefer composition over inheritance - however remember that for each particular situation, the other approach might be better.
Composition is:
class A
{
B b;
};
Inheritence is:
class A : public B
{
};
Use the first when the relationship is "has-a" and the latter when it is "is-a".
Your example is a loose type of composition - if the member is a pointer, it doesn't (necessarily) signify ownership.
This question already has answers here:
C++ inheritance, base methods hidden
(2 answers)
Closed 8 years ago.
In the following code:
struct X{
void stream(int){}
};
struct Y : public X{
void stream(int, int){}
};
int main()
{
Y y;
y.stream(2);
}
Why X::stream(int) is not inherited?
Or it is hided with Y::stream(int, int). If so, why it hidden, not overridden?
Names in derived classes do indeed hide identical names in base classes. This is deliberate. If the base class changes, you don't suddenly and silently want to see a different overload set in your derived class.
To unhide base names explicitly, add using X::stream; into your derived class.