繁体   English   中英

如何取消引用用New创建的指针而不进行复制?

[英]How can I dereference a pointer created with New without copying?

在下面的代码片段中,我通过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必须包含对象。

我已经在这个问题上工作了一段时间,任何帮助都会很棒。

行为正确

这是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 ,因此您无法在其外部分配元素,然后使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的向量,它们是智能指针 ,可以一次不再需要时为您取消分配对象。

如果需要指针向量,则不能应用此替代方法。 然后,您不能对vector之外的每个单个对象使用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,那么您实际上不需要首先使用指针。 只需创建您的对象并将其移动到矢量中即可,但是请确保不要再使用原始对象!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM