Lilo
Lilo

Reputation: 341

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

Upvotes: 0

Views: 85

Answers (2)

Lilo
Lilo

Reputation: 341

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

Upvotes: 1

Jean-Bernard Jansen
Jean-Bernard Jansen

Reputation: 7870

Implement it through a common class. I would rewrite your code like this:

class Exception : public std::exception {
    static const char* MESSAGE = "Exception"
    static const int MAX_MESSAGE_LENGTH = 200;
    mutable char composedMessage[MAX_MESSAGE_LENGTH];

public:
    virtual const char* name() const throw() {
        return MESSAGE;
    }

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

class ShoulderROMException : public Exception {
    static const char* MESSAGE = "ShoulderROM exception";
public:    
    virtual const char* name() const throw() {
        return MESSAGE;
    }
};

class KinectInitFailedException : public ShoulderROMException {
    static const char* MESSAGE = "Kinect initialization failed."
public:
    virtual const char* name() const throw() {
        return MESSAGE;
    }
};

If you dont want so much implementation in the Exception class, add another from which both ShoulderROMException and KinectInitFailedExceptionwill inherit.

There is other issues with your code: The MESSAGE members should be static, and your way to deal with strings is not very C++ish. I would also add that inlining a virtual function does not make any sense.

Upvotes: 1

Related Questions