Search code examples
c++exceptionduplicatescode-duplicationgeneralization

How can I get the same method code in a subclass without code duplication?


I have the following code:

#include <exception>

class Exception : public std::exception {
private:
    const char* MESSAGE = "Exception"

public:
    inline virtual const char* what() const throw() {
        return this->MESSAGE;
    }
};

class ShoulderROMException : public Exception {
private:
    typedef Exception super;
    const char* MESSAGE = "ShoulderROM exception";

protected:
    static const int MAX_MESSAGE_LENGTH = 200;
    mutable char composedMessage[ShoulderROMException::MAX_MESSAGE_LENGTH];

public:
    virtual const char* what() const throw() {
        strcpy(this->composedMessage, super::what());
        strcat(this->composedMessage, " -> ");
        strcat(this->composedMessage, this->MESSAGE);
        return this->composedMessage;
    }
};

class KinectInitFailedException : public ShoulderROMException {
private:
    typedef ShoulderROMException super;
    const char* MESSAGE = "Kinect initialization failed."

public:
    virtual const char* what() const throw() {
        strcpy(this->composedMessage, super::what());
        strcat(this->composedMessage, " -> ");
        strcat(this->composedMessage, this->MESSAGE);
        return this->composedMessage;
    }
};

This produces log entries looking like this: Exception -> ShoulderROM exception -> Kinect initialization failed. This is exactly what I want but I would like to avoid the obvious code duplication and can't seem to find a(n elegant) way to do so.

Would be really nice, if someone could help me out here. :)

Best regards, Lilo


Solution

  • Thanks for all your help. It got me inspired. With some additional ideas of a fellow student I came up with this solution which works great. :)

    #include <exception>
    
    class Exception :
        public std::exception {
    private:
        static const std::string MESSAGE = "Exception";
    
    protected:
        std::string composedMessage;
    
    public:
        Exception() :
        composedMessage(this->MESSAGE) {
        }
    
        virtual const char* what() const throw() {
            return this->composedMessage.c_str();
        }
    };
    
    class ShoulderROMException :
        public Exception {
    private:
        static const std::string MESSAGE = "ShoulderROM exception";
    
    public:
        ShoulderROMException() {
            this->appendMessage(this->MESSAGE);
        }
    
        virtual void appendMessage(std::string message) {
            this->composedMessage += " -> ";
            this->composedMessage += message;
        }
    };
    
    class KinectInitFailedException :
        public ShoulderROMException {
    private:
        static const std::string MESSAGE = "Kinect initialization failed.";
    
    public:
        KinectInitFailedException() {
            this->appendMessage(this->MESSAGE);
        }
    };
    

    I looked at the problem from the wrong side: top-down instead of bottom-up. ^^

    Thanks for your help anyway and best regards, Lilo