c++ - c++ `override`/`final` 说明符的反义词是什么?

标签 c++ c++11 inheritance class-hierarchy modifiers

=> 是否有说明符(可能是 firstno_override)防止覆盖未知的基函数?

当一个虚函数被添加到一个基类时,我想得到一个编译器错误,这个基类的签名与派生类中已经存在的虚函数具有相同的签名。


编辑 4:为了保持这个问题的简单性和相关性,这里又是

原始伪代码

  • 抽象 class B : A 具有 private: virtual void fooHasBeenDone() = 0;
  • class C : B implements private: virtual void fooHasBeenDone() override { react(); }
  • 现在 class A 得到一个新的 private: virtual void fooHasBeenDone();
  • 但是新的 A::foo 可能与原来的 B::foo 有所不同。

和一个具体的例子

  • 抽象 class B : Avirtual void showPath() = 0; 表示 PainterPath
  • class C : B implements virtual void showPath() override { mPath.setVisible(); }
  • 现在 class A 得到一个新的 virtual void showPath(); 表示文件路径
  • 现在,当 A 调用 showPath() 时,B 显示 painterPath 而不是某些文件路径。

当然这是错误的,然后我应该将 B::showPath() 重命名为 B::showPainterPath() 并实现 B::showPath () override 也是。我只想得到编译器的通知。


这是一个编译真实世界的例子:

#include <iostream>
#define A_WITH_SHOWPATH

class A
{
#ifdef A_WITH_SHOWPATH
public:
    void setPath(std::string const &filepath) {
        std::cout << "File path set to '" << filepath << "'. Display it:\n";
        showPath();
    }
    // to be called from outside, supposed to display file path
    virtual void showPath() {
        std::cout << "Displaying not implemented.\n";
    }
#else
    // has no showPath() function
#endif  
};

class B : public A
{
public:
    virtual void showPath() = 0; // to be called from outside
};

class C1 : public B {
public:
    virtual void showPath() override {
        std::cout << "C1 showing painter path as graphic\n";
    }
};

class C2 : public B {
public:
    virtual void showPath() override {
        std::cout << "C2 showing painter path as widget\n";
    }
};


int main() {
    B* b1 = new C1();
    B* b2 = new C2();

    std::cout << "Should say 'C1 showing painter path as graphic':\n";
    b1->showPath();
    std::cout << "---------------------------\n";
    std::cout << "Should say 'C2 showing painter path as widget':\n";
    b2->showPath();
    std::cout << "---------------------------\n";

#ifdef A_WITH_SHOWPATH
    std::cout << "Should give compiler warning\n or say \"File path set to 'Test'. Display it:\"\n and \"Displaying not implemented.\",\n but not \"C1 showing painter path as graphic\":\n";
    b1->setPath("Test");
    std::cout << "# Calling setPath(\"Test\") on a B pointer now also displays the\n#  PainterPath, which is not the intended behavior.\n";
    std::cout << "# The setPath() function in B should be marked to never override\n#  any function from the base class.\n";
    std::cout << "---------------------------\n";
#endif
    return 0;
}

运行它并查看文本输出。


作为引用,一个具有特定用例的旧示例(PainterPath 实例):

https://ideone.com/6q0cPD (链接可能已过期)

最佳答案

firstno_override 等说明符的功能本身并不存在。可能是因为它可能会造成困惑。然而,它可以通过改变方法来轻松实现。

应该在基类中使用 final 说明符 添加任何新方法。这将有助于获得任何匹配签名的编译器错误。因为,它会让后续的派生类方法签名自动成为同类中的“第一”。稍后可以删除 final 关键字,因为它仅用于“第一手验证”。

在新添加的基本方法之后添加和删除 final 关键字类似于使用 debug (g++ -g) 选项编译二进制文件,这有助于修复错误。在生产中,调试选项被删除以进行优化。

从你的例子:

class A {};  // no method, no worry

class B {
  public: virtual void showPath() = 0;  // ok
};
...

现在不小心在 A 中添加了类似的方法,导致错误:

class A {
  public: virtual void showPath() final;  // same signature by chance
  // remove the `final` specifier once the signature is negotiated
}; 
class B {
  public: virtual void showPath() = 0;  // ERROR
};

因此必须协商新的 A::showPath() 和现有的 B::showPath() 之间的签名,然后通过删除 final 继续 说明符。

关于c++ - c++ `override`/`final` 说明符的反义词是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38656443/

相关文章:

C++ 创建文件时出错(名称基于其他文件名)

c++ - 为什么 std::map emplace 需要 gcc 上的复制构造函数?

javascript - Javascript 中的类继承

c++ - 我可以在 C++ 中创建一个匿名的即时类(接口(interface)的实现)吗

c++ - 如何避免在 C++ 的派生类中重复基类构造函数参数?

java - 对象类继承

c++ - 在 C++ 中将时间 append 到字符串时出现访问冲突错误

c++ - Windows 中无法解析的外部符号

c++ - 相同的接口(interface)对象句柄(切片和 pimpl)

C++无法执行二进制文件