从指针访问[]运算符

时间:2011-12-13 17:55:10

标签: c++ pointers operators

如果我定义一个指向定义[]运算符的对象的指针,是否有直接从指针访问此运算符的方法?

例如,在下面的代码中,我可以使用指针的Vec运算符直接访问empty()的成员函数(例如->),但是如果我想访问[]运算符我需要先获取对象的引用,然后调用运算符。

#include <vector>

int main(int argc, char *argv[])
{
    std::vector<int> Vec(1,1);
    std::vector<int>* VecPtr = &Vec;

if(!VecPtr->empty())      // this is fine
    return (*VecPtr)[0]; // is there some sort of ->[] operator I could use?

return 0;
}

我可能错了,但看起来(*VecPtr).empty()效果不如执行VecPtr->empty()。这就是为什么我在寻找(*VecPtr)[]的替代品。

7 个答案:

答案 0 :(得分:35)

您可以执行以下任何操作:

#include <vector>

int main () {
  std::vector<int> v(1,1);
  std::vector<int>* p = &v;

  p->operator[](0);
  (*p)[0];
  p[0][0];
}

顺便说一下,在std::vector的特定情况下,您也可以选择:p->at(0),即使它的含义略有不同。

答案 1 :(得分:8)

return VecPtr->operator[](0);

......会做的。但实际上,(*VecPtr)[0]形式看起来更好,不是吗?

答案 2 :(得分:3)

您可以将其用作VecPrt->operator [] ( 0 ),但我不确定您会发现它不那么模糊。

答案 3 :(得分:2)

(*VecPtr)[0]完全没问题,但如果您愿意,可以使用at功能:

VecPtr->at(0);

请注意,如果索引不在范围内,这(与operator[]不同)将抛出std::out_of_range异常。

答案 4 :(得分:2)

还有另一种方法,你可以使用对象的引用:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v = {7};
    vector<int> *p = &v;

    // Reference to the vector
    vector<int> &r = *p;
    cout << (*p)[0] << '\n'; // Prints 7
    cout <<    r[0] << '\n'; // Prints 7

    return 0;
}

这样,rv相同,您可以(*p)替换所有出现的r

警告:这只有在不会修改指针(即更改指向的对象)时才有效。

请考虑以下事项:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v = {7};
    vector<int> *p = &v;

    // Reference to the vector
    vector<int> &r = *p;
    cout << (*p)[0] << '\n'; // Prints 7
    cout <<    r[0] << '\n'; // Prints 7

    // Caveat: When you change p, r is still the old *p (i.e. v)
    vector<int> u = {3};
    p = &u; // Doesn't change who r references
    //r = u; // Wrong, see below why
    cout << (*p)[0] << '\n'; // Prints 3
    cout <<    r[0] << '\n'; // Prints 7

    return 0;
}

r = u;错误,因为您无法更改引用: 这将修改r v)引用的向量 而不是引用另一个向量(u)。 所以,同样,只有在仍然使用引用的情况下指针不会改变时,这才有效。

这些示例仅因为vector<int> ... = {...};

而需要C ++ 11

答案 5 :(得分:1)

值得注意的是,在C ++ 11中,std :: vector有一个成员函数&#39; data&#39;返回指向底层数组(const和非const版本)的指针,允许您编写以下内容:

VecPtr->data()[0];

这可能是

的替代方案
VecPtr->at(0);

会产生很小的运行时间开销,但更重要的是它的使用意味着在调用之前你不会检查索引的有效性,这在你的特定例子中是不正确的。

有关详细信息,请参阅std::vector::data

答案 6 :(得分:-2)

由于范围检查,人们建议您使用->at(0)。但这是我的建议(以其他观点):

从不使用->at(0)!它真的很慢。你会牺牲性能只是因为你懒得自己不检查范围吗?如果是这样,你不应该用C ++编程。

我认为(*VecPtr)[0]没问题。