conectionist
conectionist

Reputation: 2914

Calling base constructor in body of derived class' constructor

I have this base class:

class BaseException
{
public:
    BaseException(string _message)
    {
        m_message = _message;
    }

    string GetErrorMessage() const
    {
        return m_message;
    }

protected:
    string m_message;
};

and this derived class

class Win32Exception : public BaseException
{
public:
    Win32Exception(string operation, int errCode, string sAdditionalInfo = "")
    {
        string message = "";
        message += "Operation \"" + operation + "\" failed with error code ";
        message += std::to_string(errCode);

        if (!sAdditionalInfo.empty())
            message += "\nAdditional info: " + sAdditionalInfo;

        BaseException(message);
    }
};

The compiler gives me the following error:

error C2512: 'BaseException' : no appropriate default constructor available

I know I could make a really long line constructing the message that would be passed to the base class in the initializer list but it seems more elegant this way.

What am I doing wrong?

Upvotes: 1

Views: 1393

Answers (2)

Rabbid76
Rabbid76

Reputation: 210890

You have to do the "construction" of the base class in the member initializer list of the constructor, but not to "call" the constructor of the base class in the body of the constructor of the derived class.

This means, instead of

Win32Exception(string operation, int errCode, string sAdditionalInfo = "")
{
    .....
    BaseException(message);
}

you have to

Win32Exception(string operation, int errCode, string sAdditionalInfo = "")
   : BaseException("")
{
    .....
}

The error message

error C2512: 'BaseException' : no appropriate default constructor available

means, that you did not define a construction of the base class BaseException in the member initializer list, but BaseException has no default constructor.
Said in simple words, the compiler didn't know what to do, because it was not specified how the base class should be constructed.

class BaseException
{
public:

    BaseException(string _message)
    : m_message(message)
    {
    }

    string GetErrorMessage() const
    {
        return m_message;
    }

protected:
    string m_message;
};


class Win32Exception : public BaseException
{
public:
    Win32Exception(string operation, int errCode, string sAdditionalInfo = "")
    : BaseException("")

    {
        string message = "";
        message += "Operation \"" + operation + "\" failed with error code ";
        message += std::to_string(errCode);

        if (!sAdditionalInfo.empty())
            message += "\nAdditional info: " + sAdditionalInfo;

        m_message = message;
     }
};

Upvotes: 3

marom
marom

Reputation: 5230

You can put the same things in another way:

class Win32Exception : public BaseException
{
    static string buildMessage(string operation, int errCode, string
                              sAdditionalInfo)
    {
        string message ;
        message += "Operation \"" + operation + "\" failed with error code ";
        message += std::to_string(errCode);

        if (!sAdditionalInfo.empty())
            message += "\nAdditional info: " + sAdditionalInfo;
        return message;
    }
public:
    Win32Exception(string operation, int errCode, string sAdditionalInfo = "") :
         BaseException(buildMessage(operation, errCode, sAdditionalInfo )
    {
    }
};

Upvotes: 5

Related Questions