首页 > 解决方案 > C ++:在没有对象实例的情况下调用非静态成员函数

问题描述

我正在查看 Godot 游戏引擎的源代码,发现了以下内容(为简单起见,省略了一些):

// popup_menu.cpp

int PopupMenu::_get_mouse_over(double x) const
{
    if (x >= get_size().width)
        return -1;
    // ...
}


// control.cpp

Size2 Control::get_size() const
{
    return data.size_cache;
}

get_size()为什么在不先实例化类型对象Control然后调用其成员函数的情况下调用该方法是合法的?我试图在我自己的文件中重新创建这种行为,但它不会像我通常期望的那样编译:

class Control
{
public:
    double get_size() const;
};

double Control::get_size() const
{
    return 5.0;
}

class PopupMenu
{
public:
    int _get_mouse_over(double d) const;
};

int PopupMenu::_get_mouse_over(double d) const
{
    return d > get_size(); // compile error, as expected
}

什么可能导致这种行为?如果您有兴趣,可以在以下位置找到每种方法的实际源代码:

第 110 行: https ://github.com/godotengine/godot/blob/master/scene/gui/popup_menu.cpp

第 1770 行: https ://github.com/godotengine/godot/blob/master/scene/gui/control.cpp

我搜索了这个问题,发现C#: calls non static member function without create object这不能回答我的问题,因为在他的例子中,实际上有一个实例可以调用该方法(而且它是一种不同的语言)。

标签: c++open-source

解决方案


因为PopupMenu派生自Control,所以 的每个实例PopupMenu也是 的实例Control

当一个成员函数PopupMenu调用get_size()时,它会在自身上调用 Control 的get_size()函数。

或者换一种说法,PopupMenu有一个get_size()功能,因为它是从Control.

在您的娱乐中,PopupMenu不源自Control因此这不适用。


推荐阅读