C++ 如何在不调用析构函数的情况下重新分配向量?

C++ 如何在不调用析构函数的情况下重新分配向量?,c++,class,c++11,vector,destructor,C++,Class,C++11,Vector,Destructor,在此代码中: Texture * a = new Texture(); Texture * b = new Texture(); buttons.push_back(*a); buttons.push_back(*b); 按钮是这样定义的向量: std::vector<Texture> buttons; 第一个代码块的第四行调用纹理a的析构函数。问题是,此析构函数删除texData和texCoords指向的值,这意味着当它被重新分配texData和texCoords时,指向垃圾数

在此代码中:

Texture * a = new Texture();
Texture * b = new Texture();
buttons.push_back(*a);
buttons.push_back(*b);
按钮
是这样定义的向量:

std::vector<Texture> buttons;
第一个代码块的第四行调用纹理a的析构函数。问题是,此析构函数删除
texData
texCoords
指向的值,这意味着当它被重新分配
texData
texCoords
时,指向垃圾数据

有没有办法使向量在重新分配时不会调用析构函数?

使用智能指针而不是原始指针。下面的清单使用了
std::unique\u ptr
。如果对象有多个所有者,也可以使用
std::shared_ptr

std::vector<std::unique_ptr<Texture>> buttons;

std::unique_ptr<Texture> a{new Texture()};
std::unique_ptr<Texture> b{new Texture()};
buttons.push_back(std::move(a));
buttons.push_back(std::move(b));
std::向量按钮;
std::unique_ptr a{new Texture()};
std::unique_ptr b{new Texture()};
按钮。向后推(标准::移动(a));
按钮。向后推(标准::移动(b));

这里有一个更大的问题。因为您有一个析构函数,所以还需要正确实现赋值运算符和复制构造函数。那么你的代码就可以正常工作了。谷歌C++和三的规则。如前所述,智能指针可以消除对三巨头的需求,因为它们将在幕后为您处理复制和删除

由于您正在动态分配数据成员
texData
texCoords
,因此您需要遵循,并定义复制构造函数和复制赋值运算符,否则您的代码将很容易被破坏,正如您所发现的那样

但是有更好的办法!不要将原始指针用作数据成员。使用
unique_ptr
s固定它们。(有可能你根本不需要它们作为指针,但我在这里给你一点怀疑的好处)。如果希望类可复制,则仍然需要定义复制构造函数和复制赋值运算符,并手动复制
unique\u ptr
所包含的内容

要使其可移动,可以显式地
=default
移动构造函数和移动赋值运算符


此外,您的代码正在泄漏内存。动态分配这些对象,然后将
推回
a复制
向量中

Texture * a = new Texture();
buttons.push_back(*a);
您正在取消引用
a
并将其副本添加到
向量中。除非你
删除一个在它超出范围之前,您已经有内存泄漏。使用
向量

vector<unique_ptr<Texture>> buttons;

buttons.push_back(unique_ptr<Texture>(new Texture()));
此外,如果您事先知道要添加的按钮数量,您可以
保留空间
以避免重新分配

buttons.reserve(num_buttons);

现在,您可能根本不需要动态分配
纹理
对象。你可能只需要

vector<Texture> buttons;
buttons.push_back(Texture());
矢量按钮;
按钮。向后推(纹理());

如果可能的话,我还会为
纹理定义一个移动构造函数和移动赋值操作符,这样当向量重新分配时,它就可以被移动,而不是被复制。

纹理是否拥有
图片
点击框
?在这种情况下,它可能应该按值或按唯一性保存
Picture
HitBox
。瞄准目标,根本没有析构函数。另外,动态分配
纹理
对象是否有充分的理由?我想提出如下建议:

#include <vector>

struct Picture {};
struct HitBox {};

struct Texture {
  Picture texData;
  HitBox  texCoords;
  void renderTex() { }
};

int main() {
  std::vector<Texture> textures(2);
}
#包括
结构图片{};
结构HitBox{};
结构纹理{
图像数据;
HitBox texCoords;
void renderTex(){}
};
int main(){
矢量纹理(2);
}

这似乎是一个XY问题。修复类会更好,这样它就可以与向量一起使用,否则就不能与向量一起使用。您需要为
纹理
类定义
noexcept
移动构造函数。请参阅。同时定义复制构造函数和赋值运算符。遵循。析构函数为什么删除
textData
texCoords
?如果对象拥有数据,为什么这些指针是直接数据成员呢?这一点很好,但您的示例不是异常安全的。(我们需要C++14快点,这样我们就可以使用
std::make_shared
)@BenVoigt到达那里。。。等一下:)谢谢。内存泄漏的原因是我试图找出问题所在,所以这段代码与优化代码有点不同。另外,如果我知道按钮的数量,我可以使用一个数组。我把答案交给了斯泰格,因为他的答案更简洁,但谢谢你提供了完整的答案answer@0ctoDragon:从技术上讲,Steger没有完全回答这个问题,尽管他的观察肯定是正确的。@BenVoigt
std::make_shared
已经在C++11中出现了。C++14将带来
std::make_unique
vector<Texture> buttons;
buttons.push_back(Texture());
#include <vector>

struct Picture {};
struct HitBox {};

struct Texture {
  Picture texData;
  HitBox  texCoords;
  void renderTex() { }
};

int main() {
  std::vector<Texture> textures(2);
}