【问题标题】:Is it possible to recognize undesirable overriding of virtual functions? [duplicate]是否有可能识别出不需要的虚函数覆盖? [复制]
【发布时间】:2014-07-28 16:10:30
【问题描述】:

例如:

struct A
{
    virtual void go() { };
};

struct B : public A
{
    void go() { };
};

函数go 的隐式覆盖可能是不可取的,因为无法识别B::go() 隐藏或覆盖了struct A 的相同函数,甚至它可能是struct @ 中不存在的新函数987654326@。 override C++11 的特性在你想要一个理想的虚函数覆盖时很有用,但在我的情况下它是不可取的,我不想覆盖函数 go(),这意味着如果我知道有一个 virtual函数我不会在 struct B 中使用 override 它。

我想要的是类似于 [[check_names]] attribute proposal 的东西,它不支持 C++11。 C++ 有语言特性吗?

顺便说一句,如果发生隐式覆盖虚函数,编译器(例如 GCC 和 VC++)是否可以选择显示警告(如果错误不可用,警告就足够了!)?如果有,你能提供一个 GCC 的例子吗?

编辑:我不是在谈论强制或语言功能,我想要的只是警告或任何能让我识别出不受欢迎的覆盖的东西。

编辑理想的可以覆盖什么?它可能类似于以下代码:

struct A
{
    virtual void go() { };
};

struct B : public A
{
    virtual void go() { };
};

或:

struct A
{
    virtual void go() { };
};

struct B : public A
{
    void go() override { };
};

或类似的使用属性。

【问题讨论】:

  • 您想禁止在所有基类中覆盖吗?如果是这样,请使用final
  • 功能隐藏不是bug,它是一个特性:-P
  • @Nasser 这不是那个 Q 的骗子。这里的问题是在类定义中检测覆盖。
  • @ccsadegh no answer 解决了它,因为目前似乎没有办法解决它,直到编译器实现它。如果您查看 G++、Visual Studio 和 clang 警告列表,则没有此类警告标志。
  • @BenVoigt 是对的,但肯定有一些语言功能可以完全禁用重载(使其成为非虚拟的,或者在链中的某处将其标记为 final)。似乎 OP 正在寻找不同的东西,如果类的用户重载“脆弱”方法,则会收到警告,除非他们以某种方式声明他们知道自己在做什么。

标签: c++ compiler-construction virtual-functions overriding


【解决方案1】:

我猜你可以使用标记,

#include <iostream>
#include <memory>

using namespace std;

struct no_override_tag
{};

struct A
{
    virtual void go() { cout <<"A::go" << endl;};
};

struct B : public A
{
    void go(no_override_tag={}) { cout << "B::go" <<endl; };
};

int main()
{
    unique_ptr<A> upA(new B);
    upA->go(); // no override, calls `A::go()` instead of `B::go()`


}

基本上,您添加一个默认初始化的no_override_tag 类型的参数作为B::go() 中的最后一个参数,这将使B::go 的签名不同,无论您在A 中声明什么。不是超级优雅,但它可以工作,但我不知道你为什么真的想这样做。

【讨论】:

  • 问题是重写是不可取的,这意味着我什至不知道我是否要重写一个函数。
  • @ccsadegh 然后将标签添加到签名中,您将确保该函数不会覆盖任何内容。无论如何,您都不能强制编译器发出警告。
  • 如果使用此方法,他必须将这个 no_override_tag 添加到每个不打算覆盖任何内容的方法中。
  • @Hsi-HungShih 这听起来像是违背了目的,因为听起来 OP 正在尝试检测 accidental 重载,其中一些子类位于类层次结构中没有意识到在父类中有一个名为go()的方法并重新定义了它。
  • 那么“对立面”可能会有所帮助:void A::go(override_tag={}) ?
猜你喜欢
  • 1970-01-01
  • 2020-06-17
  • 2017-07-11
  • 1970-01-01
  • 2022-01-13
  • 2016-05-24
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
相关资源
最近更新 更多