正确使用用户定义类型的 std::vector.push_back()

Posted

技术标签:

【中文标题】正确使用用户定义类型的 std::vector.push_back()【英文标题】:proper use of std::vector.push_back() with a user defined type 【发布时间】:2012-06-04 20:04:17 【问题描述】:

我使用当前的 vector.push_back() 方法遇到了分段错误(我认为)。

下面是一些示例代码:

所以我有我的班级僵尸

class Zombie

    public:
       Zombie();
       ~Zombie();

       SDL_Surface* image;

       SDL_Rect box;

       bool dead;

   protected:

   private:
       // gets random coordinates around the screen
       SDL_Rect get_zombie_rect();
 ;

构造函数为:

Zombie::Zombie()
   :
   dead(false),
   image(load_image("Player.png")),
   box(get_zombie_rect())



并且 Zombie 有一个处理程序类来使用一个名为 create_new_zombie() 的函数来管理向量。 (这里有问题)

void Zombie_Manager::create_new_zombie()

   Zombie newZombie;
   zombies.push_back(newZombie);

这是将元素添加到向量的正确方法吗?

我能够通过使用指针获得一个工作版本,但必须有一种更简单、更正确的方法来实现这一点,对吧?

如果 std::vector.push_back() 浅拷贝其新元素,为什么会出现 seg 错误?我的假设错了吗?

【问题讨论】:

我希望你意识到image 是未初始化的垃圾。 如何实现复制构造函数:en.wikipedia.org/wiki/Copy_constructor What is The Rule of Three?的可能重复 我不认为另一个问题的答案所回答的每个问题都是重复的,是吗? @Chris :我认为这是另一个问题是常见问题解答的时候。 【参考方案1】:

你需要实现一个拷贝构造函数和一个赋值运算符。

zombies.push_back(newZombie);newZombie 的副本推送到向量中。当方法进入时,原来的newZombie就被销毁了。我愿意打赌,在~Zombie() 你打电话给delete image;

因为你没有合适的拷贝构造函数和赋值运算符,所有的拷贝都是无效的,因为它们会包含悬空指针。

始终遵循三法则 - 如果需要实现析构函数,还需要实现 c-ctor 和赋值运算符。

【讨论】:

而且由于对象包含原始指针,它需要是一个 deep 副本。或者更好的是使用shared_ptr 为什么编译器不为我们实现一个? @0A0D 确实如此,但它执行的是浅拷贝。副本中的指针image 指向与原始位置相同的位置。所以当原始的被销毁时,副本中的指针会悬空。 考虑到这是我们正在谈论的 SDL,我认为任何地方都没有真正的 delete。无论如何,悬空指针 很可能是问题所在。如果 C++11 是一个选项,我建议还实现一个移动构造函数,以便能够有效地使用 STL 容器(无需以任何形式存储指针)。

以上是关于正确使用用户定义类型的 std::vector.push_back()的主要内容,如果未能解决你的问题,请参考以下文章

添加用户定义类型 C++

使用用户定义的类键入提示

存储用户地理位置数据的正确类型是啥?我可以在 DbGeography 中存储准确性吗?

检查输入的类型是不是正确

具有用户定义表类型的 SQL Server 存储过程

使用 id vs _id 实现用户记录的正确方法