Extending a class

断了今生、忘了曾经 提交于 2019-12-04 13:42:51

It largely depends on what these functions are. Given your application, I’ll go ahead and assume that the functions you want to add are there to handle additional error types.

To keep it simple, let’s assume that each function (let’s call it handle) simply gets passed an error object which it analyses and either handles, or doesn’t handle. It returns a bool to indicate this.

Then you could have the following (simplified) error_handler class:

class error_handler {
public:
    using handler_t = bool (*)(error const&);
    std::vector<handler_t> handlers;

    // …

    void add_handler(handler_t handler) {
        handlers.push_back(handler);
    }

    void handle_error(error const& error) {
        for (auto const& handler : handlers)
            if (handler(error))
                break;
    }
};

This is assuming that your errors are represented by an instance of class error (and that you’re using C++11 – the syntax changes slightly otherwise).

Now, this class definition is fixed. You can add other handlers, defined in other files, simply by calling add_handler`. Here are two examples:

// Simple logging “handler”. Needs to be added first!

extern error_handler global_error_handler;

bool log_handler(error const& error) {
    std::cerr << error.message() << '\n';
    return false; // We only log, we don’t handle.
}

global_error_handler.add_handler(log_handler);
// Handler for missing dog food

extern error_handler global_error_handler;

errno_t const MISSING_DOG_FOOD = 42;

bool dog_food_missing(error const& error) {
    if (error.code() != MISSING_DOG_FOOD)
        return false;

    global_dog_food_container.add(some_food());
    return true;
}

global_error_handler.add_handler(dog_food_missing);

In C++ you cannot modify a class without modifying the class block and adding your function definition (i.e. in error.h)

If you cannot modify the header file, then your only options are to either inherit the class, or write non-member functions that operate on the class (but those will only be able to see public members)

The only way to extend a class without modifying its original definition is by creating a new class derived from it. Perhaps you should be more specific with what you're trying to do. Does the existing code that uses error_handler have to be affected by your changes? For example, if you simply want to add a function that will log the error in a different way, and only intend to use that function in your new code, you could make a normal, non-member function that accepts a reference error_handler, but a cleaner way would be to create a my_error_handler (derived) class with the new method. An pointer/reference to an instance of my_error_handler can be freely converted to a pointer/reference to error_handler if you wish to pass it to existing code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!