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

时间:2009-03-13 08:54:57

标签: c++ pointers containers iterator

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

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

我是否需要将const_iterator强制转换回myObject,然后返回该地址?

9 个答案:

答案 0 :(得分:83)

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

&(*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
}

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

答案 1 :(得分:13)

返回&amp; iterator将返回迭代器的地址。如果要返回引用元素的方法,则返回迭代器本身。

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

在这两种情况下,根据STL的实现情况,很难通过每次经常发生的随机错误进行调试。

评论后编辑:'是的,我不想返回迭代器a)因为它的const,而b)肯定它只是一个本地的临时迭代器? - Krakkos'

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

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

答案 2 :(得分:3)

返回迭代器不是一个好主意。当对向量(反转\删除)的修改发生时,迭代器变为无效。此外,迭代器是在堆栈上创建的本地对象,因此返回它的地址根本不安全。我建议你使用myObject而不是矢量迭代器。

修改 如果对象是轻量级的,那么最好返回对象本身。另外,返回指向存储在向量中的myObject的指针。

答案 3 :(得分:3)

只要您的矢量仍然在全球范围内,您就可以返回:

&(*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());

答案 4 :(得分:1)

您可以使用向量的数据功能:

  

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

如果不希望指针指向第一个元素,而是通过索引,则可以尝试,例如:

//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;

答案 5 :(得分:0)

说,你有以下内容:

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

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

请参阅dirkgently&anon's的答案,你可以调用函数而不是开始函数,这样你就可以没有必须写*,但只能写&

代码示例:

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.

答案 8 :(得分:0)

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

return iterator._Ptr;