如何在不复制的情况下取消引用使用 New 创建的指针
How can I dereference a pointer created with New without copying?
在下面的代码片段中,我通过 new 运算符创建一个对象并将其分配给指针。我想做的是将它指向的对象添加到向量中。似乎正在发生的事情是我正在很好地创建对象,然后当我取消引用它时,这将创建对原始对象的引用。因此,当我将此引用分配给向量时,它会创建一个副本,而我想要实际的对象。任何帮助将不胜感激。
std::vector<Object> OBJVec;
Object *O = new Object();
/*Edits some of the internals*/
addToVec(*O); //Here is the beginning of the problem: this passes a reference to the content of O.
void addToVec(Object OParam){ //Here Creates a copy of O instead of passing the actual content.
OBJVec.push_back(OParam); // Pushes a copy of content instead of content.
}
*注意:上面的代码是我试图完成的代码的非常简化的版本。
关于此接口的代码的说明,此代码与 OpenGL 交互,因此 OBJVec 必须包含对象。
我已经在这个问题上工作了很长时间,任何帮助都会很棒。
行为是正确的
这是std::vector::push_back
的签名
void push_back( const T& value );
void push_back( T&& value );
取消引用指针时,现在具有对原始对象的引用。将左值引用传递给push_back
时,将选取第一个重载。
在您的第二种情况下,它也是一个左值,因此仍然选择第一个重载......您无法在push_back
上躲避复制,除非您传递rvalue
或明确std::move
它
如果你想要指针,那就让你的容器成为指针的容器。如果需要引用,请让您的容器对您的对象reference_wrapper
但是,如果您执行这些路由,则需要执行额外的内存管理工作
由于std::vector
处理自己的内存分配(默认情况下)1,因此您不能在其外部分配元素,然后使向量指向它,除非您使向量value_type本身成为指针,即std::vector<Object*>
,并将指针本身传递给addToVec
。
std::vector<Object*> OBJVec; // Make a vector of pointers instead of objects
Object *O = new Object();
addToVec(O); // Do not dereference here
void addToVec(Object *OParam) { // Use a pointer here as the argument
OBJVec.push_back(OParam);
}
但是,一旦将元素从向量中删除并且不再使用它们,就需要解除分配元素。为了简化这一点,您可以改用 unique_ptr
s 的向量,这是智能指针,一旦不再需要,就会为您释放对象。
如果需要指针向量,则无法应用此解决方法。然后,您不能对向量之外的每个对象都使用 new
。这必然会导致对象被单独分配,而不能确保连续的内存布局,这是任何采用数组的 OpenGL 函数所要求的。您需要分配一个带有new Object[count]
的数组,或者干脆完全放弃手动内存的想法,只使用对象向量而不分配其外部的元素。
1)你可以改变这种行为,但仍然不可能像你目前所做的那样,在向量之外单独分配每个元素。
我认为这应该更好(这样你就不会复制任何东西):
std::vector<Object*> OBJVec;
Object *O = new Object();
addToVec(O);
void addToVec(Object* OParam){
OBJVec.push_back(OParam);
}
在 C++98 中没有移动的概念,因此您必须改用指针向量并在那里复制对原始对象的引用。在 C++11 中,您确实具有移动语义,因此您可以使用 std::move
从字面上移动对象。但是,我不确定这在您的情况下是否是一个好主意。
首先,如今使用裸new
不被认为是一种好习惯。您应该使用一些智能指针或您自己的 RAII 包装器。在您的情况下,我只需使用std::unique_pointer
(C++11 - 或boost::unique_pointer
),然后只是一个可以安全地移动指针的std::vector<std::unique_pointer<your_type>>
(您无法复制std::unique_pointer
)。这种方法没有真正的开销,因此如果您需要堆分配和唯一所有权,这可能是要走的路。
如果你不需要堆分配并且你使用的是 c++11,那么你一开始就不需要使用指针。只需创建您的对象并随时将其移动到矢量内 - 但是,请确保您永远不会再次使用原始对象!
- 在将 new 与指针一起使用时,创建数组的指定长度
- 在C++中,如果我可以直接将整数分配给指针而不使用"new",为什么要使用"new"?
- 传递给放置 new 的指针是否是指向其对象表示形式的非 UB 指针?
- 删除使用 new 创建的 2D 或 3D 指针
- 基类指针:在哪里使用 new 和 delete
- 双指针在使用 new 时不调用对象构造函数
- 'new'和'='与指针的区别
- 哪些资源是由智能指针管理的,而它们的内存不是由new分配的
- (C++)如何在不导致 mem 泄漏的情况下将指针传递到分配了'new'的函数?
- C++:为什么可以在没有事先使用 new 的情况下在指向结构的指针上使用 delete?
- 为什么运算符"new"需要指针才能工作?
- 将指针返回使用New创建的数组数组
- "new"不会将内存分配给作为类的数据成员的指针
- 带"new"的指针和带"&variable"的指针有什么区别
- 基于索引的 alloca 返回的指针访问和"placement new"的效果
- 将内存分配给 2D 数组时,“new int*[rowCount];”的含义是什么?是 2D 数组,是指向数组的指针数组
- 使用 new: "potentially uninitialized pointer"将对象数组动态分配给指针
- 使用 malloc 而不是 new 会导致 free():指针错误无效
- 如何将一系列指针分配给Usinig New
- 如何将`new`用于数组的指针