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

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

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

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

Krakkos asked 2019-10-09T13:56:11Z
9个解决方案
82 votes

返回迭代器指向的事物的地址:

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

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

answered 2019-10-09T13:56:39Z
13 votes

返回&iterator将返回迭代器的地址。 如果要返回引用元素的方式,请返回迭代器本身。

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

在这两种情况下,根据STL的实现方式,很难调试,因为随机错误经常发生。

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

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

现在有了const-ness。 如果调用者希望通过返回的元素(无论是指针还是迭代器)执行修改,则应使用非常量迭代器。 (只需从迭代器的定义中删除“ const_”)。

David Rodríguez - dribeas answered 2019-10-09T13:57:53Z
3 votes

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

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

aJ. answered 2019-10-09T13:58:32Z
3 votes

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

&(*iterator)

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

我将其重写为:

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());
Aaron Saarela answered 2019-10-09T13:59:37Z
1 votes

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

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

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

//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;
answered 2019-10-09T14:00:18Z
0 votes

说,您具有以下条件:

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

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

但是,与STL设计保持一致,如果您打算稍后将其传递给STL算法,建议不要返回迭代器。

dirkgently answered 2019-10-09T14:01:02Z
0 votes

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

Naveen answered 2019-10-09T14:01:29Z
0 votes

请参阅dirkgently和anon的答案,您可以调用front函数而不是begin函数,因此您不必编写*,而只需编写&

代码示例:

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.
answered 2019-10-09T14:02:03Z
0 votes

我不确定是否需要返回迭代器指向的事物的地址。您需要的只是指针本身。 您将看到STL的迭代器类本身为此实现了_Ptr的使用。 因此,只需:

return iterator._Ptr;
arviman answered 2019-10-09T14:02:31Z
translate from https://stackoverflow.com:/questions/641864/returning-a-pointer-to-a-vector-element-in-c