Extending a class

假装没事ソ 提交于 2020-01-23 02:42:08

问题


EDIT Answered: Although my original question didn't explain my needs in exactly the way the answer provided by Konrad Rudolph addressed them, He (by accident or design) essentially wrote for me what I was trying to write! The class itself does not get extended, but has it's functionality extended by making the class aware of new functions which allow it (the class) to handle a wider array of issues. My grateful thanks for an excellent answer which in turn is also a great tutorial, even if it does require some ahemm light? reading of books by me ;-).

I am sure that this a very basic question, but I am trying to self teach C++, and the reference books which I am using are providing answers which I do not understand.

For my project I am defining a class error_handler {} which processes exception messages and error numbers from the programs various points. It will log the error to a file and/or print the message to the screen using various member functions.

My goal is to create this so that it has it's own .h and .cpp files, and if I later need to extend it simply add a a new member function to handle some more obscure type of error manipulation.

My question then is this:

Since in error.h I have the code:

class error_handler
{
  // ctor dtor copy logger screen functions defined
}

And in error_handler.cpp I complete those definitions,

How can I simply simply add a new function to the class? I do not wish to sub class it, simply extend it.

For a use case scenario assume that error_handler is a class defined in a proprietary package where I am not free to modify the source directly, but am allowed to extend it in separate code.

EDIT: Answers and comments thus far seem to indicate I am trying to do something the language isn't meant to do. If so then so be it, I have learned something here. In the hopes that this is not the case I will leave the question open for a bit to see what else might wander onto this post......


回答1:


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);



回答2:


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)




回答3:


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.



来源:https://stackoverflow.com/questions/20999263/extending-a-class

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