【问题标题】:C++ virtual function not recognizedC++ 虚函数无法识别
【发布时间】:2012-06-03 17:59:57
【问题描述】:

我正在使用 CodeBlocks,但我有以下无法编译的代码。

(这是关于一些 C++ 的陷阱,所以我唯一想问的是为什么它不能编译)

代码如下:

#include <iostream>
using namespace std;

class Shape
{
        public:
                Shape();
                virtual void reset();
        private:
                int color;
};

class Point : public Shape
{
        private:
        double a,b;
};

void Shape::reset()
{
        cout<<"Shape reset\n";
}

void Point::reset()
{
        Shape::reset();
        cout<<"Point reset";
}

Shape::Shape()
{
        reset();
}

int main()
{
        Shape s;
        Point o;
}

我收到以下错误:

no `void Point::reset()' member function declared in class `Point'

【问题讨论】:

    标签: c++ class virtual overriding


    【解决方案1】:

    您需要在Point 类主体中添加函数声明:

    class Point : public Shape
    {
    public:
        virtual void reset();
    private:
        double a,b;
    };
    

    virtual 是不必要的,因为它在基类中声明为virtual。但添加它作为提醒会很有帮助。)

    【讨论】:

    • 哦,谢谢。虽然它可以通过从 Shape 扩展 Point 直接工作,但现在我发现它没有。
    • @delegat - 为什么您需要声明覆盖的主要原因是调用优化。编译器通常知道对象的确切类型,在这种情况下,它会优化 VMT 访问(直接调用方法而不是虚拟调用)。但是,如果Point::reset 的实现仅在其自己的编译单元中可见,这将导致来自其他编译单元的Point 对象上的错误调用Shape::reset,这些编译单元知道Point,但不知道Point::reset .
    【解决方案2】:

    应该这样声明:

    class Shape
    {
           public:
                   Shape();
                   virtual void reset(){};
           private:
                   int color;
    };
    

    注意括号,因为虚函数什么都不做,你可以在声明中添加括号。由于它是一个虚函数,因此它被设计为在继承基类时重新定义。所以不能在你的Point::reset() 函数中真正调用Shape::reset()。同样在您的Point 类中,您需要重新定义新函数。像这样:

    class Point : public Shape
    {
         public:
             void reset();
    }
    

    那么你就可以使用Point::reset这个函数了。

    【讨论】:

      猜你喜欢
      • 2015-08-16
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 2011-07-10
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多