在c ++中返回指向向量元素的指针

Posted

技术标签:

【中文标题】在c ++中返回指向向量元素的指针【英文标题】:Returning a pointer to a vector element in c++ 【发布时间】:2010-10-13 02:45:14 【问题描述】:

我在全局范围内有一个 myObjects 向量。 我有一种方法,它使用std::vector<myObject>::const_iterator 遍历向量,并进行一些比较以找到特定元素。 找到所需元素后,我希望能够返回指向它的指针(向量存在于全局范围内)。

如果我返回&iterator,是返回迭代器的地址还是迭代器指向的地址?

我是否需要将const_iterator 转换回一个 myObject,然后返回它的地址?

【问题讨论】:

我建议你阅读 Scott Meyers 关于迭代器使用的这篇文章:ddj.com/cpp/184401406 他提供了关于将 const_iterator 转换为迭代器等的指南。 【参考方案1】:

返回迭代器指向的东西的地址:

&(*iterator)

编辑:澄清一些困惑:

vector <int> vec;          // a global vector of ints

void f() 
   vec.push_back( 1 );    // add to the global vector
   vector <int>::iterator it = vec.begin();
   * it = 2;              // change what was 1 to 2
   int * p = &(*it);      // get pointer to first element
   * p = 3;               // change what was 2 to 3

不需要指针向量或动态分配。

【讨论】:

我认为将指针返回到存储在向量中的对象并不是一个好主意。如果向量在我们获得指针后有人执行 push_back() 会发生什么。矢量可能会调整大小,指针可能会变得无效,不是吗? 迭代器也是如此。 是的,这就是为什么我认为最安全的方法是退回副本。 复制可能会很昂贵,并且(尽管在这种情况下可能不是)如果您想修改向量中的对象怎么办? 寻找完全相同问题的答案,我遇到了这个线程,觉得任何有同样问题的人都应该知道:向量的重新分配使所有引用无效,指针和迭代器。在向量中间插入/删除,使受影响索引之后的所有指针、引用和迭代器无效。资料来源:sgi.com/tech/stl/Vector.html、***.com/questions/3329956/…。在这种情况下,List 容器可能是一种替代方案。【参考方案2】:

返回迭代器不是一个好主意。当对向量(inversion\deletion)进行修改时,迭代器变得无效。此外,迭代器是在堆栈上创建的本地对象,因此返回相同的地址根本不安全。我建议您使用 myObject 而不是向量迭代器。

编辑: 如果对象是轻量级的,那么最好返回对象本身。否则返回指向存储在向量中的 myObject 的指针。

【讨论】:

【参考方案3】:

说,你有以下几点:

std::vector<myObject>::const_iterator first = vObj.begin();

那么向量中的第一个对象是:*first。要获取地址,请使用:&amp;(*first)

但是,为了与 STL 设计保持一致,如果您打算稍后将它传递给 STL 算法,我建议您返回一个迭代器。

【讨论】:

我想返回一个指向向量中的 myObject 的指针...如何找到该指针的实现我的更改,因此我不想返回一个迭代器。【参考方案4】:

返回 &iterator 将返回迭代器的地址。如果你想返回一种引用元素的方式,则返回迭代器本身。

请注意,您不需要将向量设为全局向量即可返回迭代器/指针,但向量中的操作可能会使迭代器无效。例如,如果新的 size() 大于保留的内存,则向向量添加元素可以将向量元素移动到不同的位置。从向量中删除给定项之前的元素将使迭代器引用不同的元素。

在这两种情况下,根据 STL 实现,可能很难调试,只是随机错误经常发生。

评论后编辑:'是的,我不想返回迭代器 a) 因为它的 const 和 b) 肯定它只是一个本地的临时迭代器? – 克拉科斯的

迭代器不比任何其他变量更多或更少是本地或临时的,它们是可复制的。您可以返回它,编译器会像使用指针一样为您制作副本。

现在有了常量。如果调用者想要通过返回的元素(无论是指针还是迭代器)执行修改,那么您应该使用非常量迭代器。 (只需从迭代器的定义中删除 'const_')。

【讨论】:

是的,我不想返回迭代器 a) 因为它的 const 和 b) 它肯定只是一个本地的临时迭代器?【参考方案5】:

您将 myObject 的副本存储在向量中。所以我相信复制 myObject 的实例并不是一项昂贵的操作。那么我认为最安全的方法是从您的函数中返回 myObject 的副本。

【讨论】:

我需要更改返回的myObject的一些属性,所以不想复制...使用指针的方法,我可以直接编辑它们。【参考方案6】:

只要您的向量保持在全局范围内,您就可以返回:

&(*iterator)

我会提醒你,这通常是非常危险的。如果您的向量曾经移出全局范围并被破坏,则任何指向 myObject 的指针都将变为无效。如果您将这些函数编写为较大项目的一部分,则返回非常量指针可能会导致某人删除返回值。这将对应用程序产生不确定的和灾难性的影响。

我将其改写为:

myObject myFunction(const vector<myObject>& objects)

    // find the object in question and return a copy
    return *iterator;

如果您需要修改返回的 myObject,请将您的值存储为指针并在堆上分配它们:

myObject* myFunction(const vector<myObject*>& objects)

    return *iterator;

这样你就可以控制它们何时被破坏。

这样的事情会破坏你的应用程序:

g_vector<tmpClass> myVector;

    tmpClass t;
    t.i = 30;
    myVector.push_back(t);

    // my function returns a pointer to a value in myVector
    std::auto_ptr<tmpClass> t2(myFunction());

【讨论】:

在指向存储在全局中的对象的指针中使用 auto_ptr 就像在踢自己的脚。我同意返回指向生命周期可以改变的对象的指针是危险的,但是您的示例也不现实。【参考方案7】:

可以使用向量的data函数:

返回指向向量中第一个元素的指针。

如果不希望指针指向第一个元素,而是按索引,那么你可以试试,例如:

//the index to the element that you want to receive its pointer:
int i = n; //(n is whatever integer you want)

std::vector<myObject> vec;
myObject* ptr_to_first = vec.data();

//or

std::vector<myObject>* vec;
myObject* ptr_to_first = vec->data();

//then

myObject element = ptr_to_first[i]; //element at index i
myObject* ptr_to_element = &element;

【讨论】:

【参考方案8】:

参考 dirkgently 和 anon 的回答,你可以调用 front 函数而不是 begin 函数,所以你 不必 必须编写*,但只有&amp;

代码示例:

vector<myObject> vec; //You have a vector of your objects
myObject first = vec.front(); //returns reference, not iterator, to the first object in the vector so you had only to write the data type in the generic of your vector, i.e. myObject, and not all the iterator stuff and the vector again and :: of course
myObject* pointer_to_first_object = &first; //* between & and first is not there anymore, first is already the first object, not iterator to it.

【讨论】:

【参考方案9】:

我不确定是否需要返回迭代器指向的东西的地址。 您所需要的只是指针本身。您将看到 STL 的迭代器类本身为此目的实现了 _Ptr 的使用。所以,就这样吧:

return iterator._Ptr;

【讨论】:

以上是关于在c ++中返回指向向量元素的指针的主要内容,如果未能解决你的问题,请参考以下文章

返回元素数量

C-const和static的区别, 指针作为函数的返回值, 指向函数的指针, 枚举

从 C++ 中的函数返回指向数组的指针?

C语言基础:C 中数组详解(多维数组传递数组给函数 从函数返回数组 指向数组的指针 )

C|指针的10种经典应用场合

在C中调用GetModuleHandle并返回函数指针的正确方法