8

Is there any way to create base class (such as boost::noncopyable) and inherit from it, which will forbid compiler to generate default constructor for derived classes, if it wasn't made by user (developer)?

Example:

class SuperDad {
XXX:
  SuperDad(); // = delete?
};

class Child : YYY SuperDad {
public:
  Child(int a) {...}
};

And result:

int main () {
  Child a;     // compile error
  Child b[7];  // compile error
  Child c(13); // OK
}
7
  • 2
    make it private. See this question stackoverflow.com/questions/10474417/… Commented Aug 6, 2015 at 18:20
  • It really works. Great thanks! It was really difficult to understand inheritance level and modifiers combination to make this works properly. Commented Aug 6, 2015 at 18:20
  • EDITED: it was an answer to previous disappeared comment. Commented Aug 6, 2015 at 18:26
  • @RAEC, this way will deprecate inheritance at all, see this topic Commented Aug 6, 2015 at 18:28
  • he can still declare his constructor with one parameter and make it public, by the way in C++11 you can actually "delete" the constuctor en.cppreference.com/w/cpp/language/default_constructor ClassName() = delete ; Commented Aug 6, 2015 at 18:38

3 Answers 3

7

Make the constructor private.

protected:
    Base() = default;
Sign up to request clarification or add additional context in comments.

2 Comments

Yea, thanks. Answer "make it private" was not completely clear at fist (@RAEC), because private modificator does pretty other thing.
According to the fair comment by Tomasz Sodzawiczny, the code from example above will compile until user defines his own non-trivial constructor for Child, if we use this approach.
4
#include <iostream>
using namespace std;


class InterfaceA
{
public:

InterfaceA(std::string message)
{
    std::cout << "Message from InterfaceA: " << message << std::endl;
}

private:
    InterfaceA() = delete;
};


class MyClass: InterfaceA
{
public:
    MyClass(std::string msg) : InterfaceA(msg)
    {
        std::cout << "Message from MyClass: " << msg << std::endl;
    }
};

int main()
{
    MyClass c("Hello Stack Overflow");
    return 0;
}

4 Comments

It's work, but you should declare public constructor with parameter in base class. Previous answer is more elegant and pretty compact, isn't it? :) Moreover, with this approach you can create InterfaceA object, which can be questionable.
he specifically said he wanted to "Forbid using default constructor in derived classes, C++" lol setting the default to the already default constructor does not help on that one. in the previous answer he can still inherit from it and use the default constructor. But its good to have diverse answers, he just acquired more knowledge than he thought he would probably haha
Yeah, of course, that's nice, thanks you (I already "+" your answer), and it's my question in topic :)
oh wow, i just realized that you were the one that asked the question, geez, sorry lol i would have probably provided you with the code and better answers before, but i thought it was someone else discussing this with me :/ sorry; hope all this helped you anyway haha
1

According to this cppreference.com article (which is basically a lawyer-to-human translation of C++ standard 12.1. section):

If no user-defined constructors of any kind are provided for a class type (struct, class, or union), the compiler will always declare a default constructor as an inline public member of its class.

The only way you can control the implicitly defined constructor of Child from SuperDad is making the compiler to define it as deleted.

You can do that by making the default constructor (or destructor) of SuperDad deleted, ambiguous or inaccessible - but then you have to define some other way to create the base class and use it implicitly from all the child constructors.

3 Comments

it will compile until user defines own Child non-trivial constructor (with arguments). So, in this case, Ben's answer is correct in context of my topic question. If I want to control creating Child's, I should understand cases of their usages and define at least one non-trivial constructor according to necessary logic.
In my understanding Ben's answer changes base class behaviour only (can't be directly instantiated), while not changing a thing about the derived class.
The point was to prevent default construction of Child by user (actually, the Child classes are kind of API) and wrong usages, so making base constructor private really affects Child behavior. Of course, there may be several interpretations of my question, cause I did not formulate it precisely enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.