#include<iostream>
using namespace std;
class Base {
private:
int b;
public:
Base(int bvalue=0) {
b = bvalue;
cout << "B's ctor" << endl;
}
~Base() { }
};
class Derv : public Base {
public:
int d;
Derv(int bval, int dval) : Base(bval),d(dval) {
cout << "D's ctor" << endl;
}
Derv(int dval) : d(dval) {
cout << "D's ctor " << endl;
}
};
int main(){
Derv D1(4,5);
Derv D2(100);
return 0;
}
The above program compiles fine and I see the output as
B's ctor
D's ctor
B's ctor
D's ctor
Since private members of Base class are not inherited, what is the memory location the Base constructor is creating the private member in?
NB: This question contains a misconception which is fully addressed in the answers.
Private members are inherited; they are just not visible from the member functions in the subclass. So in an instance of Derv, b and d will likely be adjacent to each other in memory (although the compiler may choose to place the variables differently). Member functions in Derv cannot see b, but if you call a function that is inherited from Base, that function will be able to see b.
I'm not sure what you're trying to ask, but whenever a derived class's constructor is called it calls its parent class's constructor first. Note that a private variable is only private to access from methods outside of a class (and its friends). Regardless of how the Base class's constructor was called, it will have access to its own private member variable b. In other words, Derv cannot access b directly, but it can call the Base constructor to modify b for it.
Furthermore, as Tomalak points out, every Derived object contains a fully-constructed Base object, private members and all. If Base was derived from another class—CommonBase, let's say—every Derived object would also contain a fully-constructed CommonBase object, as well.
In the interests of being thorough, note that unless you explicitly specify otherwise, derived classes will also implicitly call the default constructor of their parent class.
Does that make sense?
Related
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).
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.
I have a doubt regarding some concept of inheritance, i am stating what i know, please correct me if i am wrong.
Private members of base class are inherited by the derived class but derived class can't access them by any means.
Protected members of base class are inherited by the derived class but derived class can't access it directly, but by the help of some of its member functions.
Now in the following code:
class A
{
protected:
A(const A&){}
A operator=(const A &){}
int t;
public:
A(int r) {t=r;}
A(){t=0;}
};
class B : public A
{
A a;
public:
void make(void)
{
//A b(a); //LINE 1 -------COPY CONSTRUCTOR BEING CALLED ---protected member of base class
cout<<t; //LINE 2 -------protected member of base class
}
};
int main()
{
B b;
b.make();
return 0;
}
Why there is error for LINE 1 coming??
Why we can't call copy-constructor for object of A?
Many many thanx in advance
A protected member can only be accessed by other members of the same complete object, during construction, destruction, or via the this pointer(*).
In your example class hierarchy, a B object has two subobjects of type A:
The base class subobject, which it gets by deriving from A, and
The data member subobject named a, which it gets by declaring a.
A member of B may only access protected members from the first A subobject, not from the second, because only the first directly uses the this pointer (note that your expression cout << t is semantically equivalent to cout << this->t).
Access to the members of the data member do not directly use the this pointer: if you tried to access this->a.t from B::make, the this pointer is not used directly to access the t. In your declaration A b(a);, the copy constructor is called not for this, but for the new A object you are constructing, the local variable named b.
(*) Or, of course, by any member in the class that declares it: any member function of B can call any other member function of B
basic c++ question i'm fairly sure. if i have a base class with a constructor that takes no parameters, and just initializes some of the protected members, does a derived class instantly call this base constructor too if it matches the parameters (wishful but unlikely thinking), and if not, is there a way to force it to automatically call said base constructor from the derived class WITHOUT having to explicitly tell it to do so in the derived class? I ask because i'm writing a wrapper of sorts and there are some protected members that i want initialized to specific values initially, and then i want to derive and manipulate this base class to my needs, but i wouldn't like an outside user to have to remember to explicitly call the base constructor or set these values within their own constructor.
Yes, the default base constructor is always called unless explicitly stated otherwise.
For example:
class A
{
public:
A() { std::cout << "A"; }
};
class B : A
{
public:
B() {}
};
int main()
{
B b;
return 0;
}
will output:
A
By "explicitly stated otherwise" I mean that you can call a different constructor from the derived class:
class A
{
public:
A() { std::cout << "A"; }
A(int) { std::cout << "AAA"; }
};
class B : A
{
public:
B() : A(1) {} //call A(int)
};
int main()
{
B b;
return 0;
}
will output
AAA
Important if you don't have a default constructor (you declare a non-default constructor and not a default one) or the default constructor is not visible (marked as private), you need to explicitly call an available constructor in the derived class.
If your base-class has a "default constructor" (a constructor that takes no parameters; either explicitly provided by you, or implicitly provided by the compiler because you didn't explicitly provide any constructors), then every derived-class constructor will automatically call that unless you specify that they call a different constructor instead.
(If your base-class doesn't have a "default constructor", because you've provided one or more constructors that take parameters and no constructor that doesn't, then it's a compile-error for a derived-class constructor not to indicate the base-class constructor it calls.)
How to instantiate a derived class object, whose base class ctor is private?
Since the derived class ctor implicitly invokes the base class ctor(which is private), the compiler gives error.
Consider this example code below:
#include <iostream>
using namespace std;
class base
{
private:
base()
{
cout << "base: ctor()\n";
}
};
class derived: public base
{
public:
derived()
{
cout << "derived: ctor()\n";
}
};
int main()
{
derived d;
}
This code gives the compilation error:
accessing_private_ctor_in_base_class.cpp: In constructor
derived::derived()': accessing_private_ctor_in_base_class.cpp:9:
error:base::base()' is private
accessing_private_ctor_in_base_class.cpp:18: error: within this
context
How can i modify the code to remove the compilation error?
There are two ways:
Make the base class constructor either public or protected.
Or, make the derived class a friend of the base class. see demo
You can't inherit from a base-class whose only constructor is private.1
So make the base-class constructor public/protected, or add another base-class constructor.
1. Unless, as Nawaz points out, you are a friend of the base class.
You can't. That's usually the reason to make the only c'tor private, disallow inheritance.