2015-09-07 2 views
0
class EventListener 
{ 
public: 
    virtual void onEvent (std::string message) = 0; 
    virtual void onEvent (std::string message, int eventCode) = 0; 
}; 

class CustomEventListener : public EventListener 
{ 
public: 
    void onEvent(std::string message) {}; 
    void onEvent(std::string message, int eventCode) {}; // I want this to throw an error 
}; 

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

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

Выполнение обеих функций не чистых на самом деле не является вариантом, потому что я хочу заставить пользователя переопределить один из них.

+0

Мой C++ ржавый: я не думаю, что вы можете оставить один из нереализованных, если вы добавите '= 0' к обоим, не так ли? Откуда вы знаете, какой из них был переопределен, и что безопасно звонить во время выполнения? – Rup

+3

Откуда вы знаете, какой пользователь предоставил?Я почти уверен, что вам нужно предоставить реализацию по умолчанию и вызывать оба в любом случае, поэтому, если пользователь переопределяет и ничего плохого. Также вы не получаете ничего, кроме ненависти к тому, чтобы сделать эту чистую виртуальную функцию, если кто-то не хочет переопределять 'onEvent', тогда они не получают событие, зачем их заставлять? – nwp

+3

Добавление еще одной чистой виртуальной функции не совсем обратно совместимо. Пользователям потребуется реализовать его (даже тривиально) и перекомпилировать их классы. – StoryTeller

ответ

2

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

Нет. Нельзя условно предотвратить переопределение функции в зависимости от других переопределений. По крайней мере, не в стандартном C++.

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

Если вы добавите новую чистую виртуальную функцию в интерфейс, то все наследующие классы, которые еще не реализуют новую функцию, станут абстрактными. Это нарушит совместимость.

Предотвращение использования пользователем одного из них не помогло бы. Вместо этого он мешает им создавать конкретный класс, который наследует интерфейс.

+0

Да, я думал, что это будет невозможно, но я не был на 100% уверен. Спасибо за уточнение. – Catalin

2

Почему не навязывает переопределить только один из них с другими реализациями:

class CustomEventListener : public EventListener { 
public: 
    virtual void onEvent(std::string message) {}; 

private: // <<<<<<<< 
    // I want this to throw an error 
    virtual void onEvent(std::string message, int eventCode) { 
     throw std::runtime_error("Deprecated"); 
    } 
}; 
+0

Идея состоит в том, что сами пользователи будут реализовывать интерфейс, чтобы они выбирали, что происходит, когда события запускаются. Извините, я допустил ошибку при написании 'CustomEventListener', создав там виртуальные функции. – Catalin

+0

@Catalin Функция переопределения/реализации должна быть фактически виртуальной. Вы можете попробовать предложить своим клиентским классам другой интерфейс, используя шаблон шаблона шаблона (https://www.google.de/url?sa=t&source=web&rct=j&url=https://sourcemaking.com/design_patterns/template_method/ cpp/1 & ved = 0CCAQFjAAahUKEwidssDDguXHAhWM1ywKHQutB60 & usg = AFQjCNFPnuiy0gyX5wGz85DenVJhDGPhEw & sig2 = cKj1lVra4i_NIPgEB5TyWQ) –

+0

@Catalin, поскольку эти функции переопределяют виртуальные функции, они неявно являются виртуальными независимо от того, отмечены ли вы так явно или нет. – user2079303

0

Поскольку пользователь2079303 ответил, вы не можете сделать это, как вы предлагали.

Однако вы можете совершить прогулку, которая могла бы сделать трюк, которого вы хотите достичь.

class EventListener 
{ 
public: 
    virtual void onEvent (std::string message) 
    { 
     throw std::runtime_error("Deprecated"); 
    } 
    virtual void onEvent (std::string message, int eventCode) 
    { 
     onEvent(message); 
    } 
}; 

Старые классы все еще могут переопределять только первый метод.

class CustomEventListener : public EventListener 
{ 
public: 
    void onEvent(std::string message) {}; 
}; 

Новые классы вынуждены (таким образом, только за исключением), чтобы переопределить один из них, так что они могут выглядеть следующим образом:

class CustomEventListener : public EventListener 
{ 
public: 
    void onEvent(std::string message, int eventCode) {}; 
}; 

К сожалению пользователи могут переопределить их обоих, но есть вы ничего не можете с этим поделать.

Чтобы правильно справиться с этой ситуацией, вы должны вызвать второй метод в своем коде.

Смежные вопросы