Расширение класса

РЕДАКТИРОВАТЬ ОТВЕТ: Несмотря на то, что мой первоначальный вопрос не объяснял мои потребности в точности так, как на них ответил Конрад Рудольф, он (случайно или намеренно) по сути написал для меня то, что я пытался написать! Сам класс не расширяется, но его функциональность расширяется за счет информирования класса о новых функциях, которые позволяют ему (классу) обрабатывать более широкий круг вопросов. Я благодарен за отличный ответ, который, в свою очередь, также является отличным учебником, даже если он требует некоторого света ahemm? чтение книг мной ;-).

Я уверен, что это очень простой вопрос, но я пытаюсь самостоятельно учить C ++, и справочники, которые я использую, дают ответы, которые я не понимаю.

Для моего проекта я определяю class error_handler {} который обрабатывает сообщения об исключениях и номера ошибок от программ различных точек. Он записывает ошибку в файл и / или выводит сообщение на экран, используя различные функции-члены.

Моя цель состоит в том, чтобы создать его так, чтобы он имел свои собственные файлы .h и .cpp, и, если мне позже понадобится расширить его, просто добавьте новую функцию-член для обработки некоторых более неясных типов обработки ошибок.

Мой вопрос тогда такой:

Так как в error.h У меня есть код:

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

И в error_handler.cpp Я дополняю эти определения,

Как я могу просто добавить новую функцию в класс? Я не хочу подкласса это, просто расширить его.

В сценарии использования предположим, что error_handler — это класс, определенный в проприетарном пакете, где я не могу напрямую изменять исходный код, но мне разрешено расширять его в отдельном коде.

РЕДАКТИРОВАТЬ: ответы и комментарии до сих пор, кажется, указывают, что я пытаюсь сделать что-то, что язык не предназначен, чтобы сделать. Если так, то так и будет, я кое-чему научился здесь. В надежде, что это не так, я оставлю вопрос открытым, чтобы посмотреть, что еще может появиться на этом посте ……

3

Решение

Это во многом зависит от того, что это за функции. Учитывая ваше приложение, я продолжу и предположу, что функции, которые вы хотите добавить, существуют для обработки дополнительных типов ошибок.

Для простоты, давайте предположим, что каждая функция handle) просто передается объект ошибки, который он анализирует и либо обрабатывает, либо не обрабатывает. Возвращает bool чтобы указать это.

Тогда вы могли бы иметь следующее (упрощенно) error_handler учебный класс:

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

Это предполагает, что ваши ошибки представлены экземпляром класса error (и что вы используете C ++ 11 — синтаксис немного меняется в противном случае).

Теперь это определение класса фиксированный. Вы можете добавить другие обработчики, определенные в других файлах, просто вызвав add_handler`. Вот два примера:

// 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

Другие решения

В C ++ вы не можете изменить класс без изменения class заблокировать и добавить определение вашей функции (т.е. в error.h)

Если вы не можете изменить файл заголовка, тогда ваши единственные варианты — либо наследовать класс, либо написать функции, не являющиеся членами, которые работают с классом (но они смогут видеть только открытые члены)

2

Единственный способ расширить класс без изменения его исходного определения — создать новый класс, производный от него. Возможно, вы должны быть более конкретными с тем, что вы пытаетесь сделать. Имеет ли существующий код, который использует error_handler должны быть затронуты ваши изменения? Например, если вы просто хотите добавить функцию, которая будет регистрировать ошибку другим способом, и намереваетесь использовать эту функцию только в своем новом коде, вы мог сделать нормальную функцию, не являющуюся членом, которая принимает ссылку error_handler, но более чистым способом было бы создать my_error_handler (производный) класс с новым методом. Указатель / ссылка на экземпляр my_error_handler может быть свободно преобразован в указатель / ссылку на error_handler если вы хотите передать его в существующий код.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector