正确使用用户定义类型的 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()的主要内容,如果未能解决你的问题,请参考以下文章