C++ - 创建类对象向量时使用删除的正确方法
Posted
技术标签:
【中文标题】C++ - 创建类对象向量时使用删除的正确方法【英文标题】:C++ - Proper method to use delete while creating a vector of class objects 【发布时间】:2017-04-03 00:42:57 【问题描述】:我看到了一些创建类对象向量的示例,其中许多使用指针和new
关键字。但是,在许多情况下,delete
不用于释放由new
分配的内存。我想知道下面这段代码是否正确使用了delete
。
我有一堂课Marker
:
class Marker
public:
Marker(int, float, float);
int marker_id();
private:
int id;
float mx;
float my;
;
它的构造函数是:
Marker::Marker(int idno, float x, float y)
//ctor
id = idno;
mx = x;
my = y;
我需要一个带有 Marker
类的对象或实例的向量 marker_vec
。因此,我编写了以下代码:
vector <Marker> marker_vec;
Marker *m = new Marker(last_id, m_x, m_y);
marker_vec.push_back(*m);
delete m;
如果我在循环中使用上述代码创建marker_vec[0]
和marker_vec[1]
,我相信delete
不会删除它们,只会释放指针m
。上述方法有什么缺点吗?
【问题讨论】:
你可以这样做,但我不明白你为什么不直接说marker_vec.emplace_back(Marker(last_id, m_x, m_y));
(或push_back)。如果您的对象复制起来很便宜(而您的对象是),则可以不使用指针。如果您要存储 OVERLAPPED
结构,您还想使用指针(我有一个烦人的错误要追踪,因为它们中的内存必须保持在同一个地方,而我的向量正在将它们复制到整个地方)。跨度>
为什么这么复杂?为什么不只是marker_vec.emplace_back(last_id, m_x, m_y);
?
您发布的代码中根本不需要指针。
@H.DJEMAI 您不必添加m = nullptr;
。这是很多人建议的风格(尽管如果对象超出范围,我不会订阅它)。 Syamprasad:不是真的,因为您仍然将 RAII Marker
对象粘贴到向量中。如果对象的复制成本不高,您需要创建一个std::vector<Marker*>
而不是std::vector<Marker>
。
@SyamprasadKR 向量元素仍然是Marker
对象。 emplace_back
将其参数转发给元素类型的适当构造函数(在本例中为 Marker
)。我的代码会导致调用复制或移动构造函数,所以 Kerrek 的更好。
【参考方案1】:
这段代码没问题,因为当你push_back时,m指针引用的内容会被复制并添加为vector
的最后一个元素。通过释放您正确设置的内存,您做得很好(对于每个 new,都有一个相应的 delete)。
vector <Marker> marker_vec;
Marker *m = new Marker(last_id, m_x, m_y);
marker_vec.push_back(*m);
delete m;
我只是认为,在这种情况下,您没有必要使用具有一种类型的 Marker 类和您的 std::vector
类型为 <Marker>
的指针。
我个人会将此代码的实现改进为静态实例化。在这种情况下,它更简单、更干净:
vector <Marker> marker_vec;
Marker m(last_id, m_x, m_y);
marker_vec.push_back*m);
但是,如果您可能有不同类型的标记之类的继承:
class HighlighterMarker : public Marker ;
和
class PenMarker: public Marker ;
只有这样,你才有意义使用动态内存并将你的向量声明为:
std::vector <Marker*> marker_vec
。这个可以存储你对任何类型的派生类Marker
的所有引用,
【讨论】:
以上是关于C++ - 创建类对象向量时使用删除的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
C++ OOP,输出对象指针向量时的空白控制台,不确定填充向量是不是正确