【问题标题】:C++ Issues with vector<Parent*>vector<Parent*> 的 C++ 问题
【发布时间】:2015-09-13 20:16:07
【问题描述】:

我有一堂课:

class Parent {
  public:
    virtual void Update() {}
};

以及扩展它的类:

class Child : public Parent {
public:
    virtual void Update() {
        /*code*/
    }
};

我将它们存储在向量中

vector<Parent*> v;

一个名为“tick”的函数将循环遍历它们并运行它们的更新函数。

问题是:当我将它们添加到向量中并立即运行“tick”时,一切正常。但是当我在其他时间点运行“tick”函数时它不起作用(该函数不仅不会被调用,它还会阻塞程序)。

我试图尽可能地分解它。 产生错误的代码应该是这样的:

class Parent {
  public:
    virtual void Update() {}
};
class Child : public Parent {
public:
    virtual void Update() {
        /*code*/
    }
};
class Main {
public:
    vector<Parent*> v = vector<Parent*>();
    void tick() {
        printf("UPDATE");
        for (Parent* &p : v)
            p->Update();
        printf("STOP\n");
    }
};

class Program {
private:
    Main m = Main();
public:
    static class Program* prog = new Program();
    void addOne() {
        Child child = Child();
        Parent* p = &child;
        m.v.push_back(p);
        /*works when tick(); here*/
    }
    void tick() {
        m.tick();
    }
}

int main(int argc, char* argv[]) {
    Program::prog->addOne();
    /*doesn't work when Program::prog->tick(); here*/
    return 0;
}

不起作用意味着它打印 UPDATE 但不打印 STOP。

【问题讨论】:

  • 恐怕你需要给我们更多的东西来处理你目前拥有的东西。你能举一个小例子来说明你描述的行为吗?
  • 显示填写vector&lt;Parent*&gt;的代码和调用Update()的代码
  • 能在调用函数的地方加上代码吗?或者更好的是,您能否粘贴一个显示您描述的行为的示例?
  • 使用smart pointers 存储在您的向量中。

标签: c++ pointers vector


【解决方案1】:

您没有显示将Child*s 添加到向量的代码,但您描述的症状提供了令人信服的证据,表明您使用了指向某种本地或临时对象的指针,这些对象超出了范围(被销毁)而向量仍然包含指针。

由于使用已删除对象的 vtable,您的程序挂起。 (段错误比挂起更有可能,但这种解释仍然是最适合症状的)。

编辑:现在您展示了该代码并证实了我的猜测:

Child child = Child();
Parent* p = &child;
m.v.push_back(p);

以您的方式使用对象指针向量存在很多缺陷,因此仅纠正这个错误不会使您站稳脚跟。但是这个错误很容易纠正:

    Parent* p = new Child();
    m.v.push_back(p);

或者根据您可能希望避免更改尚未向我们展示的代码的其他内容,相同运行时行为的更丑陋(但可能更兼容)的源代码是:

    Child& child = *( new Child());
    Parent* p = &child;
    m.v.push_back(p);

无论哪种方式,关键是您正在创建一个带有new 的对象,直到您明确地delete 它才会消失,而不是创建一个名称一出就消失的本地对象范围。

如果您未能添加代码以最终删除对象,则您的设计的一个缺陷(以及早期评论告诉您使用智能指针的原因)是内存泄漏。正如您所展示的,在 main() 的生命周期中存在的结构中,未能清理它的实际内存泄漏没有任何后果,可以安全地忽略。但是编码和忽略此类泄漏是一个坏习惯,如果您尝试更有趣的项目,将会给您带来麻烦。

【讨论】:

    猜你喜欢
    • 2013-08-19
    • 1970-01-01
    • 2011-08-25
    • 2021-06-08
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2022-09-30
    • 2011-04-23
    相关资源
    最近更新 更多