How the compiler do composition in inheritance C++? - c++

How the compiler do composition in inheritance?
suppose that I create an object of a derived class where both the base class and the derived class contain via composition object of other classes. I want some example to explain constructors and destructors.

I'm not going to make this overly easy for you, given it does indeed look like homework. If you can think through and understand what's below - good luck to you....
The base class's constructor is invoked, which will - for each member variable in order of declaration in the base class - call either the constructor corresponding to arguments specified in the base class initialisation list or the default constructor if any (otherwise the member's left uninitialised, though sometimes e.g. earlier zero-initalisation of the memory the object is contained in - perhaps due to new (p) T() notation or being static - will guarantee specific values anyway). Then, the derived constructor does the same for its own data members. Destruction happens in reverse order.

If you need to demonstrate the basic principles, you could use some variants of:
struct M { // Marker
int id;
M(int i) : id(i) { cout << "\tconstruction M" <<id<< endl; }
~M() { cout << "\tdestruction M" <<id<< endl; }
};
struct B { //Base
M mb;
B() : mb(1) { cout << "construction B (body finished)" << endl; }
~B() { cout << "destruction B (body finished)" << endl; }
};
struct D : public B { //Derived
M md;
D() : md(2) { cout << "construction D (body finished)" << endl; }
~D() { cout << "destruction D (body finished)" << endl; }
};
Of course, it's simplified, but it shows that the base is constructed before the derived, and members are constructed before constructore body is executed. It shows as well as that destruction is performed in reverse order of construction.
But that's only the most obvious. You should aslo show examples demonstrating in which order members are constructed when there are severals, and what happens in multiple inheritance, as well as the case of static members.

Related

Understanding how to initialize constructors in the Multiple Inheritance

I having hard time in solving those kind of question. In an exam I going to take in a few days, they show a program in C++ which has Multiple Inheritance:
struct X {
X(){cout << "X" << endl;}
};
struct A : virtual X {
int i;
A(){cout << "A" << endl;}
};
struct B : A {
int i;
B(){cout << "B" << endl;}
virtual void f() {cout << "f" << endl;}
};
struct C : A {
int i;
C(){cout << "C" << endl;}
C(int i){cout << "C2" << endl;}
virtual void g() {cout << "g" << endl;}
};
struct D : virtual B, virtual C {
int i;
D( int i) : C(i), B() {cout << "D" << endl;}
};
And show some code from main:
D* d = new D(2014);
C* c = d;
B* b = d;
And than ask "what will be the output?" I don't need the solution, I can always
just run or debug it but I need to understand the intuition because I will not have the debugger with me on the exam. Now I know the algorithm I need to follow:
5 Initialization shall proceed in the following order:
— First, and only for the constructor of the most derived class as
described below, virtual base classes shall be initialized in the
order they appear on a depth-first left-to-right traversal of the
directed acyclic graph of base classes, where “left-to-right” is the
order of appearance of the base class names in the derived class
base-specifier-list.
— Then, direct base classes shall be initialized in declaration order
as they appear in the base-specifier-list (regardless of the order of
the mem-initializers).
— Then, nonstatic data members shall be initialized in the order they
were declared in the class definition (again regardless of the order
of the mem-initializers).
— Finally, the body of the constructor is executed. [Note: the
declaration order is mandated to ensure that base and member
subobjects are destroyed in the reverse order of initialization. ]
But I really having bad time solving them, it does not make any sense. Is it possible to show the intuition, maybe a trick or tip on solving those kind of questions? Maybe to show dark corners? Maybe somehow to write down all the classes/structs, write the vbase classes somehow in order to easy see to output?

why constructors are called if they are not inherited?

the code is printing all the constructors. i read that constructors are not inherited when we derive a class from another class. then why creation of c is invoking constructors from b and a
class A
{
public:
A() { cout << "A's constructor called" << endl; }
};
class B
{
public:
B() { cout << "B's constructor called" << endl; }
};
class C: public B, public A // Note the order
{
public:
C() { cout << "C's constructor called" << endl; }
};
int main()
{
C c;
return 0;
}
When the document you read said constructors are "not inherited", what it means is that if class A defines a constructor A::A(int x), then a child class B will not automatically have a constructor that takes an int.
However, it's still necessary to initialize the values of the parent class; otherwise, the parent object might be in an invalid state. Constructors are used to initialize classes, so means one of the parent class' constructors must be called from the child constructor's initializer list. If the parent class has a default constructor, that one gets called by default. That's what you see in your example. If the parent doesn't provide a default constructor, you have to specify which one you want called:
class A
{
public:
A(int x) { cout << "A's constructor called" << endl; }
};
class C: public A
{
public:
C()
: A(7) /* compilation will fail without this line */
{ cout << "C's constructor called" << endl; }
};
Constructors are not inherited in the traditional sense.
Classes are what's inherited.
But in order to construct a class, its constructor needs to be called. That's its job. Hard rule, no exceptions.
When you inherit one class from a second class, constructing the first class requires the second class to be constructed too. Because the first class always contains the second class. Another hard rule, no exceptions. That's what "inheritance" means.
So, constructing the first class will invoke its constructor. Then, to construct the second class its constructor will also need to be called (actually the second class gets constructed first, then the first class's construction takes place).
And that's why both constructors will be used.
i read that constructors are not inherited when we derive a class from another class
That is correct. However, you seem to have misunderstood the meaning of that.
Let's say you have:
struct A
{
A(int) {}
};
struct B : A
{
B() : A(0) {}
};
Given the above, you won't be able to use:
B b(10);
since A(int) is not inherited by B.
That's the crux of your misunderstanding.
then why creation of c is invoking constructors from b and a
However, when you construct a B, a constructor of B is called to initialize its members. A constructor of A must also be called so that the sub-object of B that corresponds to A can be initialized.
There are couple of ways to initialize the A-part of B.
You can use a constructor of A explicitly in the member initialization list by using the syntax:
B() : A(0) {}
Leave the member initialization empty, in which case the default constructor of A is called.
B() {}
That is equivalent to:
B() : A() {}
In the example I presented, that will result in a compiler error since the default constructor of A has been deleted by providing another constructor that is different than the default constructor.
Coming back to your implementation of the default constructor of C, you have:
C() { cout << "C's constructor called" << endl; }
That is equivalent to
C() : B(), A() { cout << "C's constructor called" << endl; }
B::B() and A::A() are called when an instance of C is constructed.
Constructors are called when classes are inherited. The inheritance basically gives the derived class instance anonymous member instances of the base classes, amongst other things. These instances need to be constructed so their constructors are called.
"Constructors are not inherited" means, that class C should and will have it's own constructors, despite fact that there were constructor of B, it will not be able to use constructor of B instead of constructor of C.
And that's exactly what you get: you get constructors of all parent classes.
When you have hierarchy of classes, and construct object from one, there will be sequential construction of all his parents, starting from the base one.
And when you will destroy them, there will be sequential destruction of him and all his parents, starting from him.
By rule: first created -- last destructed.
By not inherited, C++11 standard means this
class A
{
public:
A(int x) {}
};
class B: public A
{
};
int main(void)
{
B b(5);
return 0;
}
This will fail to compile because A(int) is not inherited. You can define B to explicitly inherit A(int) by
class B: public A
{
using A::A;
};
In your case you are defining all default ctors, and which explicitly defined or not, still exist, and will be called as part of the object initialization due to your C c declaration.
C++ inheritance basically creates a class made of parts of its super-classes. For example:
class A {
public:
A() {
std::cout << "Constructor A" << '\n';
}
};
class B : public A {
public:
B() {
std::cout << "Constructor B" << '\n';
}
};
class C : public B {
public:
C() {
std::cout << "Constructor C" << '\n';
}
};
Class C is actually class C, with a class B part, and a class A part. So in order to construct class C, we need to construct each of its parts by calling the constructors for those parts. The order of these constructors is from the most-base class to the most-derived class (in this case A to C). Most-base being the class at the top of the inheritance tree, and most-derived being the class at the bottom.
This same rule applies to destructors as well. The only difference is that the destrutors are called from most-derived to most-base (C to A).

Ensure safety while using CRTP

Consider following snippet of code making using of CRTP
#include <iostream>
struct Alone
{
Alone() { std::cout << "Alone constructor called" << std::endl; }
int me {10};
};
struct Dependant
{
explicit Dependant(const Alone& alone)
: ref_alone(alone)
{ std::cout << "Dependant called with alone's me = " << alone.me << std::endl; }
const Alone& ref_alone;
void print() { std::cout << ref_alone.me << std::endl; }
};
template <typename D>
struct Base
{
Base() { std::cout << "Base constructor called" << std::endl; }
D* getDerived() { return static_cast<D*>(this); }
Dependant f { getDerived()->alone };
void print() { f.print(); }
};
struct Derived : Base <Derived>
{
Derived() { std::cout << "Derived constructor called " << std::endl; }
Alone alone {};
void print() { Base::print(); };
};
int main()
{
Derived d;
d.print();
}
original link http://coliru.stacked-crooked.com/a/79f8ba2d9c38b965
I have a basic question first
How does memory allocation happen when using inheritance? I know the constructors are called from Base to Derived, but it seems that when I do
Derived d;
memory equivalent to sizeof(D) is allocated, and then constructors are called. Is my understanding correct here? (This would explain printing uninitialised member)
Considering the above example in mind, would you suggest/recommend any best practices when it comes to CRTP?
memory equivalent to sizeof(D) is allocated, and then constructors are called
How else could it possibly work? You can't construct an object in memory that isn't allocated yet. Memory allocation always comes before object construction.
Considering the above example in mind, would you suggest/recommend any best practices when it comes to CRTP?
The standard practices for the CRTP: don't call into the CRTP in a constructor/destructor. This is also true of virtual functions. Virtuals are dynamic polymorphism, while CRTP is static polymorphism. But they're both using the same basic mechanism: a base class that defines an interface that the derived class must implement.
And just like with virtual functions, trying to call it in constructors/destructors won't do what you mean. The only difference is that with virtual functions, the compiler will actually keep you from getting undefined behavior. Whereas with the CRTP, you just get breakage.
Note that this includes default member initializers, which for the purpose of non-aggregates are just shorthand for constructor initialization lists.

Multiple Inheritances [duplicate]

I have a class A and another class that inherits from it, B. I am overriding a function that accepts an object of type A as a parameter, so I have to accept an A. However, I later call functions that only B has, so I want to return false and not proceed if the object passed is not of type B.
What is the best way to find out which type the object passed to my function is?
dynamic_cast should do the trick
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
The dynamic_cast keyword casts a datum from one pointer or reference type to another, performing a runtime check to ensure the validity of the cast.
If you attempt to cast to pointer to a type that is not a type of actual object, the result of the cast will be NULL. If you attempt to cast to reference to a type that is not a type of actual object, the cast will throw a bad_cast exception.
Make sure there is at least one virtual function in Base class to make dynamic_cast work.
Wikipedia topic Run-time type information
RTTI is available only for classes that are polymorphic, which means
they have at least one virtual method. In practice, this is not a
limitation because base classes must have a virtual destructor to
allow objects of derived classes to perform proper cleanup if they are
deleted from a base pointer.
Dynamic cast is the best for your description of problem,
but I just want to add that you can find the class type with:
#include <typeinfo>
...
string s = typeid(YourClass).name()
This is called RTTI, but you almost surely want to reconsider your design here, because finding the type and doing special things based on it makes your code more brittle.
Just to be complete, I'll build off of Robocide and point out that typeid can be used alone without using name():
#include <typeinfo>
#include <iostream>
using namespace std;
class A {
public:
virtual ~A() = default; // We're not polymorphic unless we
// have a virtual function.
};
class B : public A { } ;
class C : public A { } ;
int
main(int argc, char* argv[])
{
B b;
A& a = b;
cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}
Output:
a is B: true
a is C: false
b is B: true
b is A: false
b is C: false
Probably embed into your objects an ID "tag" and use it to distinguish between objects of class A and objects of class B.
This however shows a flaw in the design. Ideally those methods in B which A doesn't have, should be part of A but left empty, and B overwrites them. This does away with the class-specific code and is more in the spirit of OOP.
You are looking for dynamic_cast<B*>(pointer)
Because your class is not polymorphic. Try:
struct BaseClas { int base; virtual ~BaseClas(){} };
class Derived1 : public BaseClas { int derived1; };
Now BaseClas is polymorphic. I changed class to struct because the members of a struct are public by default.
Your description is a little confusing.
Generally speaking, though some C++ implementations have mechanisms for it, you're not supposed to ask about the type. Instead, you are supposed to do a dynamic_cast on the pointer to A. What this will do is that at runtime, the actual contents of the pointer to A will be checked. If you have a B, you'll get your pointer to B. Otherwise, you'll get an exception or null.
As others indicated you can use dynamic_cast. But generally using dynamic_cast for finding out the type of the derived class you are working upon indicates the bad design. If you are overriding a function that takes pointer of A as the parameter then it should be able to work with the methods/data of class A itself and should not depend on the the data of class B. In your case instead of overriding if you are sure that the method you are writing will work with only class B, then you should write a new method in class B.
If you can access boost library, maybe type_id_with_cvr() function is what you need, which can provide data type without removing const, volatile, & and && modifiers. Here is an simple example in C++11:
#include <iostream>
#include <boost/type_index.hpp>
int a;
int& ff()
{
return a;
}
int main() {
ff() = 10;
using boost::typeindex::type_id_with_cvr;
std::cout << type_id_with_cvr<int&>().pretty_name() << std::endl;
std::cout << type_id_with_cvr<decltype(ff())>().pretty_name() << std::endl;
std::cout << typeid(ff()).name() << std::endl;
}
Hope this is useful.
Use overloaded functions. Does not require dynamic_cast or even RTTI support:
class A {};
class B : public A {};
class Foo {
public:
void Bar(A& a) {
// do something
}
void Bar(B& b) {
Bar(static_cast<A&>(b));
// do B specific stuff
}
};

Override or remove an inherited constructor

Here is some C++ code:
#include <iostream>
using namespace std;
class m
{
public:
m() { cout << "mother" << endl; }
};
class n : m
{
public:
n() { cout << "daughter" << endl; }
};
int main()
{
m M;
n N;
}
Here is the output:
mother
mother
daughter
My problem is that I don't want the m's constructor to be called when I create N. What should I do ?
AFAIK, you cannot remove inherited constructor.
The problem in your example comes from incorrect class design.
Constructor is normally used for allocating class resources, setting default values, and so on.
It is not exactly suitable to be used for outputting something.
You should put
n() { cout << "daughter" << endl; }
Into virtual function.
In general - if you have a need to remove inherited constructor, then you probably need to rethink/redesign your class hierarchy.
class m
{
public:
m(bool init = true) { if (init) cout << "mother" << endl; }
};
class n : m
{
public:
n() : m(false) { cout << "daughter" << endl; }
};
or if you don't want it to be public
class m
{
protected:
m(bool init) { if(init) Init(); }
Init() { cout << "mother" << endl; }
public:
m() { Init(); }
};
class n : m
{
public:
n() : m(false) { cout << "daughter" << endl; }
};
Two solutions:
Don't derive n from m. Check that you really have interface reuse (that you rely on a polymorphic interface) instead of implementation reuse. In the latter case, prefer making an m* a member of n and then only create the m object when needed. This would be my preferred solution.
You probably don't want ms contructor to be called because it does something which you don't want. Move that code which you don't want to execute out of ms constructor into a dedicated init() function or the like, and then call it as needed. I don't recommend this because you end up with a stateful interface.
Constructors are never inherited. What happens is that C++ generates a default nullary constructor that initializes the base classes and members of class type. The base classes are always initialized and there is no way to prevent this, so if you don't want the base class constructors to be called, don't inherit from the base class.
Object of any class contains in it sub-objects of all its superclasses. And all of them must be constructed before construction of main object. Part of this construction is calling one of base class constructors and it cannot be omitted. You can only choose constructor to be called.