Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid copying all constructors in subclasses

Tags:

So a base class has multiple constructors:

sf::Sprite()
sf::Sprite(const Texture& texture)
sf::Sprite(const Texture& texture, const IntRect& rectangle)

And I'm subclassing this class multiple times:

class Sub : public sf::Sprite {
    public:
        Sub() : sf::Sprite() {};
        Sub(const Texture& texture) : sf::Sprite(texture) {};
        Sub(const Texture& texture, const IntRect& rectangle) : sf::Sprite(texture, rectangle) {};

        // My subclass specific code
};

As you see, I have to repeat these three constructors for every subclass. Is there a way to avoid this, since the constructors usually don't do anything special? Sometimes I need some class specific initialization though, so it's not always viable to just straight out copy everything.

like image 580
Markus Meskanen Avatar asked May 16 '17 15:05

Markus Meskanen


People also ask

Do subclasses inherit copy constructors?

Copy constructor is not inherited.

Do subclasses inherit all constructors?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

Do subclasses need constructors?

A subclass needs a constructor if the superclass does not have a default constructor (or has one that is not accessible to the subclass). If the subclass has no constructor at all, the compiler will automatically create a public constructor that simply calls through to the default constructor of the superclass.

Do subclasses have default constructors?

In general, if a class does not define a no-argument constructor, all its subclasses must define constructors that explicitly invoke the superclass constructor with the necessary arguments. If a class does not declare any constructors, it is given a no-argument constructor by default.


2 Answers

You can accomplish this by inheriting constructors (since C++11).

If the using-declaration refers to a constructor of a direct base of the class being defined (e.g. using Base::Base;), all constructors of that base (ignoring member access) are made visible to overload resolution when initializing the derived class.

e.g.

class Sub : public sf::Sprite {
    public:
        using sf::Sprite::Sprite;

        // My subclass specific code
};

If the inherited constructors is used to initialize a Sub, the sf::Sprite subobject is initialized using the inherited constructor, and all other members of Sub are initialized as if by the defaulted default constructor.

If there're some special cases need to be processed, you still can define constructor(s) in Sub, the inherited constructor with the same signature will be hidden.

As with using-declarations for any other non-static member functions, if an inherited constructor matches the signature of one of the constructors of Derived, it is hidden from lookup by the version found in Derived.

like image 64
songyuanyao Avatar answered Oct 05 '22 03:10

songyuanyao


You can use the using keyword to inherit the constructor of your base class, excluding the special ones (default, copy, move). To shorten your default constructor simply use = default. If you want class specific initialization you can simply write the constructor again, just as you do now.

class Sub : public sf::Sprite {
    public:
        Sub() = default;
        using sf::Sprite::Sprite;

        Sub(const Texture& texture) 
        {
           // your custom code.
        };

        // My subclass specific code
};
like image 36
Sebastian Stern Avatar answered Oct 05 '22 03:10

Sebastian Stern