派生类中的非虚函数C++名称与“final”说明符冲突
C++ same name for non-virtual function in derived class conflicts with `final` specifier
这给人一种完全新手问题的感觉,但是为什么当final
说明符用于B::operator()
时,下面的代码无法编译?
struct A
{
virtual void operator()() const = 0;
};
// the CRTP-component is not really necessary here
// but it possibly makes more sense in that it could be applied like this in reality
//
template<typename Derived>
struct B : A
{
virtual void operator()() const override final
{
static_cast<Derived const&>(*this).operator()();
}
};
struct C : B<C>
{
void operator()() const
{
//do something
}
};
int main()
{
C()();
}
G++ 打印以下错误消息:
main.cpp:17:14: error: virtual function 'virtual void C::operator()() const'
void operator()() const
^
main.cpp:9:22: error: overriding final function 'void B<Derived>::operator()() const [with Derived = C]'
virtual void operator()() const override final
^
我会认为它可以工作,因为非虚拟C::operator()
不会覆盖其基类中的虚拟函数?我怎样才能把它带到工作中(--不改变C::operator()
的名字)?
编辑:正如几位用户指出的那样,答案很简单,派生类中的 virtual
-关键字是多余的(而我认为省略它会阻止继承)。但是,我问这个问题的目标 - 即整个动态和静态继承层次结构中的一致接口 - 可以通过在整个过程中使用非虚拟operator[]
来解决,并通过虚拟函数apply
A
和B
的类耦合:
struct A
{
void operator()() const
{
this->apply();
}
protected:
virtual void apply() const = 0;
};
template<typename Derived>
struct B : A
{
void operator()() const
{
static_cast<Derived const&>(*this).operator()();
}
protected:
virtual void apply() const override final
{
this->operator()();
}
};
struct C : B<C>
{
void operator()() const
{
//do something
}
};
int main()
{
C()();
}
如果在基类中声明virtual
函数,则无论是否使用 virtual
关键字,派生类中都会隐式virtual
具有相同名称和参数列表的函数。您不能使C::operator()()
成为非虚拟的。
生类中的函数与基类中的虚函数具有相同的签名,将覆盖基类中的该虚函数。这使它成为一个虚函数,即使/尽管派生类中的声明不使用 virtual
关键字。
这是无法更改的,因此,如果您确实需要在派生类中具有相同名称的函数,该函数不会覆盖基类中的虚函数(并且在此过程中,成为虚拟本身,在这种情况下,违反了B
中的final
),则需要更改派生类中函数的签名。这可能意味着不同的名称、不同的参数列表或不同的限定符。不过,我会非常谨慎地对待后两者 - 编译器将能够整理出你造成的混乱,但许多人类读者可能会(很容易)感到惊讶。
如果我正在审查这样的代码,我可能会认为这是一个问题,作者需要提供非常坚实的理由来说明为什么真正有必要获得批准。
作为重写(因为它与基类中的虚拟函数具有相同的签名),重写与其基类中指定的final
冲突。
一种解决方法(或者更确切地说是解决方法)是给该函数一个默认参数,以便它具有不同的类型,因此不是覆盖,更好的方法是修复设计。
- 写入位置0x0000000C时发生访问冲突
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- C++尝试深度复制唯一指针时出现内存访问冲突
- 错误:使用通用引用的声明冲突
- 如何解决GTest和LibTorch联动冲突
- 两个运营商的一些奇怪的冲突<<
- 是否有技术原因阻止 Java 中的 final C++ 像 const 一样严格?
- 如何在多个线程中创建 QSql数据库连接时防止名称冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- C++17 十六进制浮点文字单精度后缀冲突?
- 结构字段名称与 GDB 中的 STL 数组冲突
- 写入访问冲突异常
- 派生类中的非虚函数C++名称与“final”说明符冲突