【问题标题】:How to access the contents of a vector from a pointer to the vector in C++?如何从指向 C++ 中向量的指针访问向量的内容?
【发布时间】:2011-10-20 05:55:15
【问题描述】:

我有一个指向向量的指针。那么,如何通过指针读取向量的内容呢?

【问题讨论】:

  • 您确定要使用指向向量的指针吗?使用参考可能更有意义。请参阅下面的帖子。

标签: c++ pointers vector


【解决方案1】:

有很多解决方案,我想出了几个:

int main(int nArgs, char ** vArgs)
{
    vector<int> *v = new vector<int>(10);
    v->at(2); //Retrieve using pointer to member
    v->operator[](2); //Retrieve using pointer to operator member
    v->size(); //Retrieve size
    vector<int> &vr = *v; //Create a reference
    vr[2]; //Normal access through reference
    delete &vr; //Delete the reference. You could do the same with
                //a pointer (but not both!)
}

【讨论】:

  • 参考部分是不好的建议,因为new 可能返回 0。
  • @Don Reba - 不是;在大多数编译器上都会引发异常:stackoverflow.com/questions/550451/…
  • 另外,如果new did 返回 0,all 对指针的操作将是错误的,而不仅仅是引用初始化。
  • 我个人更喜欢(*v)[2]; 而不是v-&gt;operator[](2),因为它更短并且仍然保留了“运营商的运营商”。
  • @godofllamas 同意了。 (*v)[2] 表示指针所在位置的索引 2,对吗?
【解决方案2】:

像访问任何其他指针值一样访问它:

std::vector<int>* v = new std::vector<int>();

v->push_back(0);
v->push_back(12);
v->push_back(1);

int twelve = v->at(1);
int one = (*v)[2];

// iterate it
for(std::vector<int>::const_iterator cit = v->begin(), e = v->end; 
    cit != e;  ++cit)
{
    int value = *cit;
}

// or, more perversely
for(int x = 0; x < v->size(); ++x)
{
    int value = (*v)[x];
}

// Or -- with C++ 11 support
for(auto i : *v)
{
   int value = i;
}

【讨论】:

  • “像其他指针一样”。我不明白这个问题。你有一个指针,所以你使用thing-&gt;member 而不是thing.member,这是唯一的区别(在 99% 的情况下,等等)
【解决方案3】:

你有一个指向向量的指针吗,因为你就是这样编码的?您可能需要重新考虑这一点并使用(可能是 const)引用。例如:

#include <iostream>
#include <vector>

using namespace std;

void foo(vector<int>* a)
{
    cout << a->at(0) << a->at(1) << a->at(2) << endl;
    // expected result is "123"
}

int main()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);

    foo(&a);
}

虽然这是一个有效的程序,但一般的 C++ 风格是通过引用而不是指针传递向量。这将同样有效,但是您不必处理可能的空指针和内存分配/清理等。如果您不打算修改向量,请使用 const 引用,如果不修改则使用非 const 引用您确实需要进行修改。

这是上述程序的参考版本:

#include <iostream>
#include <vector>

using namespace std;

void foo(const vector<int>& a)
{
    cout << a[0] << a[1] << a[2] << endl;
    // expected result is "123"
}

int main()
{
    vector<int> a;
    a.push_back(1);
    a.push_back(2);
    a.push_back(3);

    foo(a);
}

如您所见,a 中包含的所有信息都将传递给函数 foo,但它不会复制一个全新的值,因为它是通过引用传递的。因此它与通过指针传递一样有效,您可以将其用作普通值,而不必弄清楚如何将其用作指针或必须取消引用它。

【讨论】:

  • 这可能是一个愚蠢的评论。但是既然你只使用了 at 方法,那么使用语法 (*a)[1] 有什么好处吗?就我个人而言,我喜欢这样,因为我变薄了它更好地反映了我的意图,这使我更容易阅读代码(优点是我的意思是至少在一种情况下性能显着提高)
【解决方案4】:
vector<int> v;
v.push_back(906);
vector<int> * p = &v;
cout << (*p)[0] << endl;

【讨论】:

    【解决方案5】:

    您可以直接访问迭代器方法:

    std::vector<int> *intVec;
    std::vector<int>::iterator it;
    
    for( it = intVec->begin(); it != intVec->end(); ++it )
    {
    }
    

    如果您想要数组访问运算符,则必须取消引用指针。例如:

    std::vector<int> *intVec;
    
    int val = (*intVec)[0];
    

    【讨论】:

      【解决方案6】:

      有很多解决方案。例如你可以使用at() 方法。

      *我假设您正在寻找等同于[] 的运算符。

      【讨论】:

      • 但是如何知道向量中的元素个数呢?
      • @user815961 v-&gt;size() 返回向量中的元素个数
      【解决方案7】:
      vector <int> numbers {10,20,30,40};
      vector <int> *ptr {nullptr};
      
      ptr = &numbers;
      
      for(auto num: *ptr){
       cout << num << endl;
      }
      
      
      cout << (*ptr).at(2) << endl; // 20
      
      cout << "-------" << endl;
      
      cout << ptr -> at(2) << endl; // 20
      

      【讨论】:

        【解决方案8】:

        将它用作数组的最简单方法是使用vector::data() 成员。

        【讨论】:

        • 使用向量的原因是抽象出它背后的底层实现(连续数组)。这违背了面向对象的原则,更不用说效率极低了,因为你分配了一个大小为 n 的全新数组,而你可以只使用 vec->at(index)。更不用说,这与原始发帖人的问题完全无关,因为您没有在任何地方使用指向向量的指针。
        • 我只是举个例子,如果我们想知道底层类型,我们可以使用vector::value_type。但它是静态解释的。我想传达的重点是 data() 是获取底层指针的成员。这就是他的问题。
        • 不,问题是vector 是否可以通过指针读取。我在 OP 中没有看到任何比这更深层次的东西。
        • @AndrewRasmussen 你能解释一下“分配一个大小为 n 的全新数组”部分吗?调用 data() 会这样做吗?
        • 想知道为什么在原始编辑中将向量复制到新数组。 (这解释了所有的不喜欢)你可以简单地使用数据指针本身。 (见这个example)但问题只是关于如何做 vec[x] 如果 vec 是一个指针。 (*vec)[x] 就是答案。还有 at(x) 方法,但请注意,它还会检查它是否超出范围。
        猜你喜欢
        • 2012-06-07
        • 2021-12-10
        • 2011-08-04
        • 2019-09-10
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        相关资源
        最近更新 更多