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.
Related
I am implementing the Decorator design pattern in c++ and I ran into this problem (code taken from https://www.studytonight.com/cpp/initializer-list-in-cpp.php):
#include<iostream>
using namespace std;
class Base_
{
public:
// parameterized constructor
Base_(int x)
{
cout << "Base Class Constructor. Value is: " << x << endl;
}
};
class InitilizerList_:public Base_
{
public:
// default constructor
InitilizerList_()
{
Base_ b(10);
cout << "InitilizerList_'s Constructor" << endl;
}
};
int main()
{
InitilizerList_ il;
return 0;
}
As the website states, this doesn't compile because the base constructor gets called before the derived constructor, and this problem is solved using initializer lists. My question is: Can this be implemented without initializer lists and if so, how? Initializer lists were introduced in c++ 11 (I think) so what if you were trying to do this in c++ 98 for example?
The syntax to delegate to the base class constructor from the derived class constructor would be as follows
class InitilizerList_ : public Base_
{
public:
// default constructor
InitilizerList_() : Base_(10)
{
cout << "InitilizerList_'s Constructor" << endl;
}
};
You're getting confused on the terminology. There is an initializer list, which looks like { for, bar, baz, ... }, there is a std::initializer_list type that can wrap an initilizer list, and then there is the class member initialization list, which is used to initialize the members in the class.
That last one is what you want and has been part of C++ since it was created. Using one would give you
InitilizerList_() : Base_(10)
{
cout << "InitilizerList_'s Constructor" << endl;
}
I come from a Python background, and currently I'm learning OOP in C++.
I'm having problems figuring out how to get the code to call the correct method in a helper class HelperBase that is inherited to HelperChild.
#include <iostream>
class HelperBase {
public:
HelperBase() {}
virtual void something() {
std::cout << "HelperBase" << std::endl;
}
};
class HelperChild : public HelperBase {
public:
HelperChild() {}
void something() {
std::cout << "HelperChild" << std::endl;
}
};
The HelperBase class i used in the class Base, where it is set as a member variable.
class Base {
public:
Base(HelperBase &helperBase) : hb(helperBase) {}
virtual void print() {
std::cout << "-- Base" << std::endl;
hb.something();
}
HelperBase hb;
};
Then this class is used as the base class of the class Child:
class Child : public Base {
public:
Child(HelperChild &helperChild) : Base(helperChild) {
helperChild.something();
}
};
The main method is
int main() {
HelperChild helperChild;
Child child(helperChild);
child.print();
return 0;
}
This outputs the following:
HelperChild
-- Base
HelperBase
Why isn't the 'HelperChild' printed in the last line? What changes do I have to do to achieve this? (I'm not sure if I have used virtual in the correct way).
EDIT: In the actual case im trying to figure out, Base::print is a really large method that I don't want to override in the Child class. I just want to change the behaviour of the helper class.
Copy constructor will NOT copy derived object, it will get sliced and create a base object.
To elaborate, you may consider copy constructor as "copy by value", every value of derived object would be copied to create a base object. Since your Helper classes have no class members, it copied nothing.
Also function is not copyable, C++ handles virtual functions by vtable. A base class would have a vtable of base class, that's why hb.something() called the base version.
Last line is printing Helper base because your Base has a HelperBase but not a derived HelperChild.
class Base {
public:
Base(HelperBase &helperBase) : hb(helperBase) {} // hp(helperBase) means you still have a helper base.
virtual void print() {
std::cout << "-- Base" << std::endl;
hb.something();
}
HelperBase hb;
};
Then in main, child.print() will call the hb.something() which belongs to HelperBase.
To achieve polymorphism, you need a pointer to take the instance of HelperChild. It's called Dependency Injection and I assumed you were trying to achieve it.
class Base {
public:
Base(HelperBase &helperBase) {
hb = &helperBase;
}
virtual void print() {
std::cout << "-- Base" << std::endl;
hb->something();
}
HelperBase* hb;
};
The HelperBase hb in class Base is always of type HelperBase - even if you call print from an instance of type Child.
There are various ways to achieve what you want. One option is to use PIMPL to store a pointer to a Helper class. A different option is to use CRTP.
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.
I was reading effective C++ and I couldn't really understand one of the mentioned benefit of initialization list.From what I understand is that initialization lists also help to avoid calling of unnecessary default constructors especially when they are not needed. So in order to test that I created a simple code example as such
class base
{
public:
base()
{
std::cout << "Default Constructor called \n";
}
base (int i)
{
std::cout << "Int constructor called \n";
}
};
class der : public base
{
private:
base b;
public:
der(int i):b(i)
{
std::cout << "Derived constructor called \n";
}
};
void main()
{
der d(12);
}
No where I assumed that only the int constructor will be called instead both the constructors of the base class are called. Could anyone please clarify this concept.
The problem is that you actually have 2 instances of base, one as a member and one as a base. Either change into der(int i):base(i),b(i) or remove the member.
Keep in mind that you are adding a member of type base to the der class, which also needs to be constructed. That member is being initialized with the constructor that doesn't take arguments. What you probably meant was:
class base
{
private:
int num;
public:
base()
{
std::cout << "Default Constructor called \n";
}
base (int i) : num(i)
{
std::cout << "Int constructor called \n";
}
};
class der : public base
{
private:
//base b;
public:
der(int i):base(i)
{
std::cout << "Derived constructor called \n";
}
};
void main()
{
der d(12);
}
der has two base instances, as explained by Ylisar. As base has default constructor, it will be implicitly called in der constructor.
Also C++ only supports below two forms of main function, there is no void main() in C++
§3.6.1 Main function
An implementation shall not predefine the main function. This function
shall not be overloaded. It shall have a return type of type int, but
otherwise its type is implementation-defined. All implementations
shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
In your der,There are two base class, one is for inheriting, another one is b(the member of der).
I am trying to understand inheritance and I need some help building two classes. The fist one is called A, the second one is called B.
A has one private integer value "m_a". It has two constructors, the default one sets m_a to 5. and another one which takes as an argument an integer called m and sets m_a's value to m. As for member functions it will have two. The first one will return m_a. The second one will print "Hello from A!". Let's move on to B. B will have a private string m_s. A default constructor which will set m_s to "asd" or to anything other than an empty string and a constructor which will take as an argument a string and set m_s to it's value. As far as functions go, firstly B will have a function that will return m_s. It will have a function which will have the same name as the print "Hello from A" function in A which will override it and it will printout "Hello from B!" instead (is that polymorphism ?).
Those are the classes needed. I have the following questions (I will post what I have created below)
Firstly, is there any way I can get to the private data fileds from the base class. For example let's say I want to take the m_s variable, add it to another one and print out their sum. Is that possible ? (and how)
Also when I try to create a class with a constructor different from the default one I get errors. I am obviously doing something wrong. The question is what.
I think those are all of my questions for now, so it is time for me to post the source code.
#include <iostream>
#include <string>
using namespace std;
class A
{
private:
int m_a;
public:
A(){m_a = 5;}
A(int m)
{
m_a = m;
}
void pm()
{
cout << "Hello from A!" << endl;
}
int get_a()
{
return m_a;
}
};
class B : A
{
private :
string m_s;
public:
B(){m_s = "asd";}
B(string s)
{
m_s = s;
}
void pm()
{
cout << "Hello from B!" << endl;
}
string get_s()
{
return m_s;
}
};
int main()
{
A a(10);
a.pm();
cout << a.get_a() << endl;
B b("asd");
b.pm();
cout << b.get_s() << endl;
cout << b.get_a() << endl;
return 0;
}
(is that polymorphism ?).
Not the way you have done it. It would be polymorphism if you had a pointer of type A* which pointed to what was actually a B object, and calling pm on that pointer correctly invoked the member function of B. This would only be possible if the pm function in A were declared as virtual, like below.
class A
{
...
virtual void pm(){
...
};
...
int main()
{
A* = new B();
A->pm(); //"Hello from B!"
}
is there any way I can get to the private data fileds from the base class
Not sure what you mean here - your example talks of a private field of the derived class.
Typically good class design means that derived class should not need to access the (private) fields of the base class, if this is needed you should make that field protected.
As to the compile error #ArunKumar got it exactly.
When you say Class B : A You inherit from A, but all the members are inherited as private by default, due to this, base class constructor is private, so you cannot use it.
However when you say Class B : public A it is the other end of the spectrum. All members of the base class retain their accesibility in the derived class (public remains public, etc)
The problem is that you're using private inheritance:
class B : A {
Inheritance through classes are private by default. Add public before A.
class B : public A {
As for your other problem...
I want to take the m_s variable, add it to another one and print out their sum.
This is easy when it comes to std::string. Just create another member function:
void addTom_s(string s) { m_s += s; }
Trying changing class B : A to class B : public A