【问题标题】:Call overloaded function from each object in std::vector从 std::vector 中的每个对象调用重载函数
【发布时间】:2025-12-08 10:25:01
【问题描述】:

我正在开发自己的 OpenGL 菜单系统。 我想要的是将与菜单相关的所有对象放在一个向量中,这样我就可以轻松地将它们全部循环:

for (auto i : menuObjects)
{
    i.checkInputs();
    i.draw();
}

我尝试过使用其他循环方法,甚至在基类的函数中添加了this->draw();,但这显然会导致无限循环。

我的基类基本上是这样的:

class menuObject
{
public:

    virtual void draw() { }
    virtual void checkInputs() { }

};

而继承的类是这样的:

class Button : public menuObject
{
public: 
    void draw()
    {
        ... drawing here ...
    }

    void checkInputs()
    {
        ... checking inputs here ...
    }

};

以下是我将它们保存在矢量中的方法:

std::vector<menuObject> menuObjects = {
    Button(... parameters here ...)
};

它永远不会进入重载函数。 我宁愿不在自己的向量中包含每个不同的菜单对象。 有任何想法吗?

【问题讨论】:

  • 你在哪里重载了任何函数?你的意思是被覆盖的函数吗?
  • 他们重载了 draw 和 checkInputs 方法
  • @GabrielAlexander 看起来不像。不过,Op 已经覆盖了这些函数,这就是为什么 SolidMercury 怀疑这可能是他们的意思。
  • 哦,是的,我自己也弄糊涂了。
  • What is object slicing?的可能重复

标签: c++ inheritance vector c++17


【解决方案1】:

您遇到的问题是您无法将不同类型的对象直接存储在向量中。

std::vector<menuObject> menuObjects = {
Button(... parameters here ...)
};

上面的代码将 Button 分割成一个 menuObject。当派生类被赋值给基类时,就会发生对象切片。与派生类相关的任何信息都会丢失。

您要做的是使用指针来实现多态性。

因此您的std::vector&lt;menuObjects&gt; 将变为std::vector&lt;menuObjects*&gt;vector&lt;std::unique_ptr&lt;menuObjects&gt;。如果此向量将负责管理 menuObjects 的生命周期,则使用后者,否则使用前者。

旁注:如果您确实使用前一个选项(即原始指针),请确保在 menuObject 的生命周期在向量的生命周期结束之前从向量中删除无效的指针。

【讨论】: