2017-01-22 57 views
-2

如果我有一个std :: vector,我可以访问一个成员,因为方括号运算符在vector类中被重载。如果我有一个指向矢量的指针,我可以取消引用指针并使用此运算符。但是用箭头 - >运算符它不会让我使用它。例如:解除引用指针时,为什么[]括号不起作用?

std::vector<int> myVector;  
std::vector<int>* pToVector; 
myVector[4] = 0;     // Works fine 
(*pToVector)[4] = 0;    // Works fine 
pToVector->[4] = 0;    // Doesn't work 
(pToVector->)[4] = 0;    // Doesn't work 

看来好像 - >箭头运算符引用指针,是否有理由不期望这会工作?或者这只是关于该语言的其中一件事情?

谢谢。

+1

前2个分配可能似乎正常工作,但您正在访问UB以外的容器边界。你需要声明它为'std :: vector myVector(5)',它将分配必要的空间来访问'myVector [4]'后两个是非法的结构 – doug

+0

这是不正确的语法。箭头运算符给你*对象。结构如此pToVector - > [4] = 0类似于* pToVector。[4] = 0.这条线(pToVector - >)[4]和这个pToVector - > [4]都不起作用 – arturx64

+0

你为什么期望它工作? 'a-> b'表示'(* a).b'。所以,'a - > [b]'可能意味着'(* a)。[]'这是没有意义的。 – HolyBlackCat

回答

1

第二两行的正确语法是:

(*pToVector)[4] = 0; 
//dereference the pointer and then call operator[] on the object returned by the dereference 

您可以使用->操作符来访问这样的普通成员函数:

pToVector->size(); 

从技术上讲,你可以尝试哟调用operator[]的名称,但它更详细。

3
std::vector<int> myVector;  
std::vector<int>* pToVector; 
myVector[4] = 0;     // Works fine. 
(*pToVector)[4] = 0;    // Works fine 
pToVector->[4] = 0;    // Doesn't work 
(pToVector->)[4] = 0;    // Doesn't work 

如果您必须使用指向对象的指针访问对象类的重载操作符,则必须显式调用它。

pToVector->operator[](4) 

...顺便说一下,访问索引外myVector.size()是未定义的行为。这包括代码中关于// Works fine的注释注释。

0

->运算符不只是取消引用,它也访问一个成员。您正在访问一个元素*,而不是成员。 ->可能已被定义为允许,但不是。

*更准确地说,一个向量可以让你访问一个对象,就像它是一个数组的元素一样,但它不会改变语法。

+0

“元素”与“成员”? C++没有这样的区别;这些术语可以互换使用。 – MSalters

+0

@MSalters你有没有C++标准引用类元素或数组成员的例子?我没有找到他们,但我可能忽略了一些东西。 – hvd

+0

@hvd:我读了你的语句,因为'' - >'正在访问一个元素“而被误导了,但没关系。 C++没有正式定义_element_,标准只在索引中有'element_type',但1.8/2几乎没有疑问。也就是说,在这个问题中'']'不访问一个数组元素,而是指向成员函数'operator []'。相同的标记,不同的含义。 – MSalters

0

->运算符是点运算符的替代品,只是它先取消引用指针。它用于访问属性(成员和函数)。对于您的操作,operator[]是属性。因此,pToVector->operator[](4)适用于(*pToVector)[4] = 0

+0

' - >'不限于数据成员,它也适用于成员函数。显然'operator []'是一个函数成员,而不是数据。 – MSalters

+0

'属性'字更合适。但我可能是指成员和方法,同时说数据字段@MSalters – snr

+0

'属性'不是一个关键字,[属性](http://en.cppreference.com/w/cpp/language/attributes)是完全不同的东西。此外,“成员和方法”毫无意义。方法是成员的一个子集。 (即成员职能)。 – MSalters

0

原因是[]是一个运算符,而短运算符语法不要求或允许成员访问运算符。这适用于成员访问运营商.->,这是合理的,因为后者只是(*a).b的简写。

E.g.全部不允许a. & b,a->^b

从技术上讲,它也适用于较罕见的.*->*。请注意,后者是而不是->后面是operator*,但指向成员指针取消引用。

相关问题