2015-09-07 52 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

正如user2079303回答,你不能像你所建议的那样做。

但是,你可能会做一些步骤,可以做你想达到的诀窍。

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

不幸的是用户也可以覆盖他们两个,但有你无能为力。

要正确处理这种情况,应该在代码中调用第二种方法。