What Is Constructor Inheritance

Inheriting constructors

If your compiler supports C++11 standard, there is a constructor inheritance using using (pun intended). For more see Wikipedia C++11 article. You write:

class A
{
public:
explicit A(int x) {}
};

class B: public A
{
using A::A;
};

This is all or nothing - you cannot inherit only some constructors, if you write this, you inherit all of them. To inherit only selected ones you need to write the individual constructors manually and call the base constructor as needed from them.

Historically constructors could not be inherited in the C++03 standard. You needed to inherit them manually one by one by calling base implementation on your own.


For templated base classes, refer to this example:

using std::vector;

template<class T>
class my_vector : public vector<T> {
public:
using vector<T>::vector; ///Takes all vector's constructors
/* */
};

What is constructor inheritance?

Inheriting Constructors means just that. A derived class can implicitly inherit constructors from its base class(es).

The syntax is as follows:

struct B
{
B(int); // normal constructor 1
B(string); // normal constructor 2
};

struct D : B
{
using B::B; // inherit constructors from B
};

So now D has the following constructors implicitly defined:

D::D(int); // inherited
D::D(string); // inherited

Ds members are default constructed by these inherited constructors.

It is as though the constructors were defined as follows:

D::D(int x) : B(x) {}
D::D(string s) : B(s) {}

The feature isn't anything special. It is just a shorthand to save typing boilerplate code.

Here are the gory details:

12.9 Inheriting Constructors


1) A using-declaration that names a constructor implicitly declares a
set of inheriting constructors. The candidate set of inherited
constructors from the class X named in the using-declaration consists
of actual constructors and notional constructors that result from the
transformation of defaulted parameters as follows:

  • all non-template constructors of X, and
  • for each non-template constructor of X that has at least one parameter with a default argument, the set of constructors that
    results from omitting any ellipsis parameter specification and
    successively omitting parameters with a default argument from the end
    of the parameter-type-list, and
  • all constructor templates of X, and
  • for each constructor template of X that has at least one parameter with a default argument, the set of constructor templates that results
    from omitting any ellipsis parameter specification and successively
    omitting parameters with a default argument from the end of the
    parameter-type-list

Why are constructors not inherited in java?

In simple words, a constructor cannot be inherited, since in subclasses it has a different name (the name of the subclass).

class A {
A();
}

class B extends A{
B();
}

You can do only:

B b = new B();  // and not new A()

Methods, instead, are inherited with "the same name" and can be used.

As for the reason:
It would not have much sense to inherit a constructor, since constructor of class A means creating an object of type A, and constructor of class B means creating an object of class B.

You can still use constructors from A inside B's implementation though:

class B extends A{
B() { super(); }
}

Inherited Constructors in C++

The default constructors are being called because Derived inherits from Base1 and Base2. Both of those bases need to be constructed when you construct a Derived object. So when you do

Derived d1(3);

You call Base1(int i). Now you need to construct the Base2 part and since you do not specify how, the compiler default constructs it. The same thing happens in

Derived d2("hello");

Since you do not specify how to construct the Base1 part in the constructor the compiler default constructs it for you. Then Base2(const string& s) is called to construct the Base2 part.

Essentially what you have is

class Derived :public Base1, public Base2
{
public:
Derived(int n) : Base1(n), Base2() {}
Derived(const std::string& str) : Base1(), Base2(str) {}
};

Inheritance of constructors in java

Don't think of the constructor as creating the instance. Think of it as initializing the instance, with respect to that particular class.

So the initialization process looks something like:

  • Allocate memory
  • Initialize object from perspective of java.lang.Object
  • Initialize object from perspective of your.package.Superclass
  • Initialize object from perspective of your.package.Subclass

(Even though you start with a call to new Subclass(...), the superclass constructor body is executed first.)

The details of object initialization are given in JLS section 12.5.

Class constructor inheritance using `extends` with passed in arguments

The parent and child are class objects and they dont have relation each other. From your code, when you call let child = new Child(), you did nothing with the x, y, w and h in your Child constructor.

The Classes are templates, the inheritance means you copy the parent's methods implementation.

You can just think the Parent and Child classes are different each other - just the Child class has all the methods that the Parent has.

When you inherit a class, you need to pass the parameters that the Parent class needs in its constructor.

You can fix it like below:

class Parent {
constructor(x, y, w, h) {
this.x = x; //if I put values directly here it works
this.y = y;
this.w = w;
this.h = h;
}
}

class Child extends Parent {
constructor(x, y, w, h) {
super(x, y, w, h); // <- Passing the parameters
this.pt1 = {x: this.x, y: this.y};
this.pt2 = {x: this.x + this.w, y: this.y};
this.pt3 = {x: this.x + this.w, y: this.y + this.h};
this.pt4 = {x: this.x, y: this.y + this.h};
}
}

let parent = new Parent(300, 50, 50, 200);
let child = new Child(300, 50, 50, 200); // <- pass the values
console.log(child.pt1)
console.log(child.pt3)


Related Topics



Leave a reply



Submit