Calling a constructor from a constructor of different class - c++

I have a class i create a constructor for it "A". Then i create another class with a constructor "B". How do I call constructor "B" from constructor of a different class i.e "A" using c++ language?

If A inherits from B then you can call the base class constructor from a constructor of A. In C++11 you have more flexibility with this and you can use delegating constructors. Otherwise, this question doesn't make much sense.
A constructor is a special kind of function which is only called when you are creating a new object. You can't call it except when you are doing that, and usually you call a constructor when you want to make a new object -- calling the constructor is not your goal, getting the new object is.

In C++ members or fields of a class which are object variables themselves, their constructor automatically get's called by the compiler, right when the class get's instantiated that is when it's own constructor has been called. The order of instantiating objects in C++ is like this, base class constructor get's called first, then member variables, then the most derived class which is your class.

This will serve your purpose.
class A {
public:
A(){
//your code
}
};
class B{
public :
B():A(){
//your code
}
};

if both the classes are not in parent child relationship, then you may compose class A into B. below is an example.
class B{
public:
B(){
cout<<"Class B constructor"<<endl;
}
};
class A{
B pbj;
public:
A(){
cout<<"Class A Constructor"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A obj1;
return 0;
}

Related

constructors inherited in c++

Excerpt from here:
Constructors are different from other class methods in that they create new objects, whereas other methods are invoked by existing objects. This is one reason constructors aren’t inherited. Inheritance means a derived object can use a base-class method, but, in the case of constructors, the object doesn’t exist until after the constructor has done its work.
Does a constructor create new object or when a object is called the
constructor is called immediately?
It is said that a constructor and destructor is not inherited
from the base class to the derived class but is the program below a
contradiction, we are creating an object of the derived class but it
outputs constructor and destructor of the base class also?
class A{
public:
A(){
cout<< Const A called<<endl;
}
~A(){
cout<< Dest A called <<endl;
}
};
Class B : public A{
public:
B(){
cout<< Const B called <<endl;
}
~B(){
cout<< Dest B called <<endl;
}
};
int main(){
B obj;
return 0;
}
Output:
Const A called
Const B called
Dest B called
Dest A called
A derived class D does not inherit a constructor from B in the sense that, specifying no explicit D constructors I can use my B(int) like to construct a new D(1);.
However, what I can do is use a base class constructor in the definition of a derived class constructor, like D::D(void) : B(1) {}.
Less abstract, suppose I have a constructor for Person that takes a gender parameter, I might wish to create a:
class Son: Person{
public:
Son(void) : Person(male) {};
};
to construct a Son, which is obviously a Person, but certainly doesn't need parameterised gender.
Destructors are 'inherited' in the sense that on the closing brace of D::~D(){} a call to ~B() is implied.

How to initialize, during construction, an abstract base class data member from a derived class instance

I want to do the equivalent of the following to initialize the data member my_abc (which I suspect won't work):
class ABC { // abstract base class
public:
virtual ~ABC {};
}
class SomeClass {
public:
SomeClass(ABC& abc); // argument will actually be instance of derived class
private:
ABC my_abc; // needs to be set from constructor argument
}
SomeClass::SomeClass(ABC& abc) : my_abc(abc)
{...} // copy construct `my_abc` from argument
I suspect this won't work when a derived class of ABC is passed to the SomeClass constructor because the copy constructor of the derived class won't be called to initialize the my_abc member.
Am I correct? If so, what should I do?
You said,
SomeClass(ABC& abc); // argument will actually be instance of derived class
and then, you have a member data
ABC my_abc;
If you initialize my_abc using abc, you will get a base class object that does not capture the derived class part. Checkout the issue of object slicing. Is that what you are hoping to accomplish? I think not.
As mentioned in the comment by πάντα ῥεῖ, you should store a reference to the base class.
ABC& my_abc_ref;
Then,
SomeClass::SomeClass(ABC& abc) : my_abc_ref(abc) {...}
shouldn't be a problem.
If you want to have a copy of the input object, you need to clone the input object and maintain the lifetime of the cloned object. You can use a smart pointer to accomplish that.
class ABC {
public:
virtual ~ABC() {}
virtual ABC* clone() const = 0;
};
#include <memory>
class SomeClass {
public:
SomeClass(ABC& abc);
private:
std::unique_ptr<ABC> my_abc;
};
SomeClass::SomeClass(ABC& abc) : my_abc(abc.clone()) {}
This just shows the mechanism. To create production quality code, you have to make policy decisions on the behavior of copy and move construtors, and copy and move assignment operators of SomeClass and implement them appropriately.
PS
The class ABC, as posted, is not an abstract base class. It does not have any pure virtual functions.

virtual base class with public/private constructor Behavior difference

if i run this code
#include<iostream>
using namespace std;
class Final;
class MakeFinal{
public:
friend class Final;
MakeFinal(){cout<<"makefinal\n";}
};
class Final: public virtual MakeFinal{
public:
Final(){cout<<"Final\n";}
};
class Derived:public Final{
public:
Derived(){cout<<"Derived\n";}
};
int main(){
//Final f;
Derived d;
return 0;
}
Output is :
makefinal
Final
Derived
But if i make MakeFinal() constructor private , compiler shows error message. What is this different constructor call hierarchy based on ?
Refer to:
C++ FAQs - virtual inheritance constructors
http://www.parashift.com/c++-faq/virtual-inheritance-ctors.html
Because of the fact that "Initialization list of most-derived-class's ctor directly invokes the virtual base class's ctor. ", your most derived needs to invoke the constructor of the virtual base directly. Therefore, for what you want to do you'd need to make the most derived class a friend too...
Furthermore, it seems that you don't understand virtual inheritance correctly. Refer to this FAQ to understand the purpose and proper use of virtual inheritance.
If your class A have private constructor, you cannot create object a of this class like that (see):
A a;
When an object b of class B that derives from A is created, base class constructor must also be called. If it is private, it cannot be called and the derived object cannot be created.

Why can't Initialize the data member of base class in the constructor initializer list of derived class?

such is the code,and with the error:"illegal member initialization: 'a' is not a base or member",what is the meaning of the error info,and why??
class A{
public:
int a;
};
class B:public A{
public:
B();
};
B::B():a(10){ // put "a(10)" into the constructor body is right
}
By the time the constructor of the derived class is invoked, the base class must already be constructed. So it's already too late. To see why it must be this way, consider:
class Base
{
public:
int i;
Base(int q) : i(q) { ; }
};
class Middle : public Base
{
public:
Middle() : Base(2) { printf("i=%d\n", i); }
};
class Derived : public Middle
{
public:
Derived() : i(3) { ; }
}
Now, think about it. The Middle constructor has to run before the Derived constructor. And the Middle constructor ensures that i is 2. So how can the Derived constructor later re-construct it with a different value?
See this answer for a more complete explanation of what's going on here. Basically, you cannot initialise A::a in the initialiser of B, because it is ill-formed according to the standard.
One more important piece of information - remember that if a class does not initialise a member object via the constructor initialization list, then the default constructor for that member will be invoked before that first statement in the base class constructor is executed. When you use the initialiser, what you are actually doing is specifying a constructor to be used INSTEAD of the default constructor.
Clearly when you are constructing a derived class, the parent class member has thus already been constructed, so you cannot reconstruct the base member again, which is what you are trying to do in this example by including it in the derived class initialisation list.
As an aside, if you all you want is to have the derived class be able to set the value of A::a to a specific value, then use the following code instead:
B::B()
{
a = 10;
}
Because the base class may want to initialize things its own way. The proper method is to call on of the base constructors in the initializer list and let the base ctor initialize itself.

protected inheritance error

#include<iostream>
using namespace std;
class base
{
protected:
int a;
public:
base(int i)
{
a=i;
}
};
class derived :protected base
{
public:
derived(){}
void show()
{
cout<<a;
}
};
int main()
{
base obj(2);
derived obj1;
obj1.show();
return 0;
}
Why is this program giving error as In constructor derived::derived():
error: no matching function for call to base::base()
Please explain. As i have read in stackoverflow that in case of inheriting as protected, protected members of base class became protected member of derived class. If I am wrong then please share a good link to clear my misconception
Once you define a constructor for any class, the compiler does not generate the default constructor for that class.
You define the parameterized constructor(base(int i)) for base and hence the compiler does not generate the no argument constructor for base.
Resolution:
You will need to define a constructor taking no arguments for base yourself.
Add this to your base class:
base():a(0)
{
}
EDIT:
Is it needed to define default constructor to every class? Or is it necessary to have the constructor that matches the derived type also present in base type?
The answer to both is NO.
The purpose of constructors in C++ is to initialize the member variables of the class inside the constructor. As you understand the compiler generates the default constructor(constructor which takes no arguments) for every class.
But there is a catch, If you yourself define (any)constructor(one with parameters or without) for your class, the compiler does not generate the default constructor for that anymore. The compiler reasoning here is "Huh, this user writes a constrcutor for his class himself, so probably he needs to do something special in the constructor which I cannot do or understand", armed with this reasoning the compiler just does not generate the default no argument constructor anymore.
Your code above and you assume the presence of the default no argument constructor(When derived class object is created). But since you already defined one constructor for your base class the compiler has applied its reasoning and now it refuses to generate any default argument constructor for your base class. Thus the absence of the no argument constructor in the base class results in the compiler error.
You must give a value to the base constructor:
class Derived : protected base
{
public:
Derived() : base(0)
{
}
};
Depending on your implementation, give the value to the base constructor. However, you may want the Derived constructor to take also int as an argument, and then pass it to the base one.
You need to implement an empty constructor in base or invoke the defined base(int) constructor explicitly from derived c-tor. Without it, when derived c'tor is activated,
it is trying to invoke base() [empty c'tor], and it does not exist, and you get your error.
You haven't defined a default constructor for Base..
When you instantiate an instance of Derived, it will call the Derived() constructor, which will in turn try to call the Base() default constructur which doesn't exist as you haven't defined it.
You can either declare an empty constructor for base Base::Base() or call the existing one as below:
#include<iostream>
using namespace std;
class base
{
protected:
int a;
public:
base(int i)
{
a=i;
}
};
class derived :protected base
{
derived(): Base(123) {} --this will call the Base(int i) constructor)
void show()
{
cout<<a;
}
};
int main()
{
base obj(2);
derived obj1;
obj1.show();
return 0;
}