为什么我无法覆盖虚函数?
Why Am I Unable to Override Virtual Function?
我试图覆盖 Vector_container 中的大小函数,但 IDE 告诉我 "Non-virtual member function marked 'override' hides virtual member function"
class Container {
public:
virtual double& operator[](int) = 0; // pure virtual function
virtual int size() const = 0; // const member function (§4.2.1)
virtual ~Container() {} // destructor (§4.2.2)
};
class Vector_container : public Container { // Vector_container implements Container
public:
Vector_container(int s) : v(s) { } // Vector of s elements
~Vector_container() {}
double& operator[](int i) override { return v[i]; }
int size() override { return v.size(); }
private:
Vector v;
};
但它不是虚函数吗?
常量在这里很重要。你的 Container
声明了一个纯虚拟的 int size() const
,而你试图覆盖 int size()
。根据我的测试,将您的覆盖声明为 const
works。
正如其他人提到的,const 的使用改变了函数的签名。我想补充一些知识,以帮助将来的其他人。
在 C++ 中覆盖函数时,如果您的编译器支持 C++11 及更高版本,请在函数签名末尾使用 override 关键字。这将从编译器中产生更多有用的信息。如果虚函数具有 override 关键字,则编译器可能会导致程序在编译时失败。如果编译器找不到具有相同函数签名的父虚函数来覆盖,则会发生错误。与 运行 时间相比,在编译时发现错误几乎总是更好。
您似乎使用了 override 关键字,因此它可能为您指明了正确的方向。我强调这一点的主要原因是我希望看到这个问题的其他人意识到您可以在编译时使用该关键字捕获错误的覆盖。
人们在行业中的常见做法是提供带有和不带 const 的基本函数。虽然许多人可能会说这违背了 const 的目的,但在某些情况下,您可能需要在非 const 函数或非 const 对象上调用 const 函数。唯一的其他选择是使用可变的,我发现很少有 C++ 程序员理解它的含义。
简而言之,const 更改了函数的签名,因此如果 const 签名匹配,则只能在子 class 上覆盖。
这是一个针对类似问题的 link,它更深入地介绍了 const 和函数签名。它还深入研究了可变和按位常量与概念常量。希望这有助于您的理解 - c++ function syntax/prototype - data type after brackets
我试图覆盖 Vector_container 中的大小函数,但 IDE 告诉我 "Non-virtual member function marked 'override' hides virtual member function"
class Container {
public:
virtual double& operator[](int) = 0; // pure virtual function
virtual int size() const = 0; // const member function (§4.2.1)
virtual ~Container() {} // destructor (§4.2.2)
};
class Vector_container : public Container { // Vector_container implements Container
public:
Vector_container(int s) : v(s) { } // Vector of s elements
~Vector_container() {}
double& operator[](int i) override { return v[i]; }
int size() override { return v.size(); }
private:
Vector v;
};
但它不是虚函数吗?
常量在这里很重要。你的 Container
声明了一个纯虚拟的 int size() const
,而你试图覆盖 int size()
。根据我的测试,将您的覆盖声明为 const
works。
正如其他人提到的,const 的使用改变了函数的签名。我想补充一些知识,以帮助将来的其他人。
在 C++ 中覆盖函数时,如果您的编译器支持 C++11 及更高版本,请在函数签名末尾使用 override 关键字。这将从编译器中产生更多有用的信息。如果虚函数具有 override 关键字,则编译器可能会导致程序在编译时失败。如果编译器找不到具有相同函数签名的父虚函数来覆盖,则会发生错误。与 运行 时间相比,在编译时发现错误几乎总是更好。
您似乎使用了 override 关键字,因此它可能为您指明了正确的方向。我强调这一点的主要原因是我希望看到这个问题的其他人意识到您可以在编译时使用该关键字捕获错误的覆盖。
人们在行业中的常见做法是提供带有和不带 const 的基本函数。虽然许多人可能会说这违背了 const 的目的,但在某些情况下,您可能需要在非 const 函数或非 const 对象上调用 const 函数。唯一的其他选择是使用可变的,我发现很少有 C++ 程序员理解它的含义。
简而言之,const 更改了函数的签名,因此如果 const 签名匹配,则只能在子 class 上覆盖。
这是一个针对类似问题的 link,它更深入地介绍了 const 和函数签名。它还深入研究了可变和按位常量与概念常量。希望这有助于您的理解 - c++ function syntax/prototype - data type after brackets