在下面的代码片段中,我通过new运算符创建一个对象并将其分配给指针。我想要做的是将它指向的对象添加到矢量。似乎正在发生的事情是我正在创建对象,然后当我取消引用它时,这会创建对原始对象的引用。因此,当我将此对Object的引用赋给向量时,它会创建一个副本,而我想要实际的对象。任何帮助都会非常感激。
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必须包含对象。
我已经解决了这个问题很长一段时间了,任何帮助都会很精彩。
答案 0 :(得分:1)
行为正确
这是std::vector::push_back
void push_back( const T& value );
void push_back( T&& value );
当您取消引用指针时,您现在可以引用原始对象。将左值引用传递给push_back
时,会选择第一个重载。
在你的第二种情况下,它也是一个左值,所以第一次重载仍然被选中......你不能躲避push_back
上的复制,除非你传递rvalue
或明确{{ 1}}它
如果你想要指针,那么让你的容器成为指针。 如果您想要参考,那么让您的容器为reference_wrapper到您的对象
但是,如果你做那些路线
,你有额外的内存管理工作要做答案 1 :(得分:1)
由于std::vector
处理自己的内存分配(默认情况下) 1 ,你不能在它之外分配一个元素,然后使vector指向它,除非你做了vector的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)你可以改变那种行为,但是仍然不可能像你现在那样在向量之外自己分配每个元素。
答案 2 :(得分:0)
我认为这应该更好(这样你就不会复制任何东西):
std::vector<Object*> OBJVec;
Object *O = new Object();
addToVec(O);
void addToVec(Object* OParam){
OBJVec.push_back(OParam);
}
答案 3 :(得分:0)
在C ++ 98中,没有移动的概念,所以你必须使用指针向量而复制在那里引用你的原始对象。在C ++ 11中,您确实具有移动语义,以便您可以使用std::move
逐字移动对象。但是,我不确定这是否是一个好主意。
首先,使用裸new
这一天并不算是一种好习惯。您应该使用一些智能指针或您自己的RAII包装器。在您的情况下,我只需使用std::unique_pointer
(C ++ 11 - 或boost::unique_pointer
),然后只使用std::vector<std::unique_pointer<your_type>>
我可以安全地移动指针(您可以&#39;复制std::unique_pointer
)。这种方法没有真正的开销,所以如果你需要堆分配和独特的所有权,这可能是要走的路。
如果你不需要堆分配,并且你在c ++ 11中,那么你真的不需要首先使用指针。只需创建您的对象并随时将其移动到向量内 - 但请确保您再也不使用原始对象!