简体   繁体   中英

The default constructor in an child of std::runtime_error

I have two exception classes that inherit from std::runtime_error. The first one, AError , works just fine.

class AError : public std::runtime_error {
public:
    const char* what() const noexcept
    {
        return "Error of type A!";
    }
};

The second one, BError , does not compile because std::runtime_error does not have a default constructor.

class BError : public std::runtime_error {
public:
    const int num_;

    BError(int n) : num_(n) {}; // ERROR: no default constructor for runtime_error

    const char* what() const noexcept
    {
        return "Error of type B!";
    }
};

It seems to me that AError should not compile because the default constructor of AError should call the default constructor of std::runtime_error in the default constructor AError . What is happening in the default constructor of AError that allows that example to compile?

It seems to me that AError should not compile because the default constructor of AError should call the default constructor of std::runtime_error in the default constructor AError.

The default ctor of AError is deleted because it inherits from a class that has no default ctor. try the following and the code won't compile

AError er;

The definition of AError compiles because it doesn't have a default constructor (one that accepts no arguments). Implicit generation of the default constructor is suppressed because std::runtime_error doesn't have one. The class definition, in itself, has no diagnosable errors, since it doesn't create any instances of the class.

There is a diagnosable error on any attempt to create an instance of AError using a default constructor

AError an_error;    // error since AError cannot be default constructed

In BError , the definition of the constructor (within class BError )

 BError(int n) : num_(n) {}; // ERROR: no default constructor for runtime_error

attempts to implicitly construct the base std::runtime_error , even though it is not listed in the initialiser list. So this definition is functionally equivalent to

BError(int n) : std::runtime_error(), num_(n) {};

and is a diagnosable error, due to the attempt - clearly visible to the compiler - to use the (non-existent) default constructor of std::runtime_error .

You can make this compile by simply using an appropriate constructor from std::runtime_error , such as

BError(int n) : std::runtime_error(""), num_(n) {};

which will call the constructor of std::runtime_error that accepts a const char * .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM