在c ++中,我们知道对于类的指针,我们使用( - >)箭头操作符来访问该类的成员,如下所示:
#include <iostream>
using namespace std;
class myclass{
private:
int a,b;
public:
void setdata(int i,int j){
a=i;
b=j;
}
};
int main() {
myclass *p;
p = new myclass;
p->setdata(5,6);
return 0;
}
然后我创建了一个“myclass”数组。
p=new myclass[10];
但是,当我通过( - &gt;)箭头操作符访问myclass
成员时,出现以下错误
base operand of '->' has non-pointer type 'myclass'
但是当我通过(。)运算符访问类成员时它可以工作。这些事让我感到困惑。为什么类I的数组必须使用(。)运算符。
答案 0 :(得分:15)
您应该阅读有助于您了解问题的pointers and reference之间的区别。
简而言之,不同之处在于:
当您声明myclass *p
时它是一个指针,您可以使用->
访问其成员,因为p
指向内存位置。
但是,只要您致电p=new myclass[10];
p
开始指向数组,并且当您致电p[n]
时,您会获得一个引用,必须使用.
来访问哪些成员。
但是,如果您使用的p->member = smth
与调用p[0].member = smth
的情况相同,那么[]
中的数字是从p
到搜索下一个数组成员的偏移量,例如(p + 5)->member = smth
与p[5].member = smth
答案 1 :(得分:7)
请注意,对于指针变量x
myclass *x;
*x
表示“获取x指向的对象”x->setdata(1, 2)
与(*x).setdata(1, 2)
相同,最后x[n]
表示“获取数组中的第n个对象”。因此,例如x->setdata(1, 2)
与x[0].setdata(1, 2)
相同。
答案 2 :(得分:4)
因为使用[]像p [3],你已经取消引用了指向数组+索引移位的指针。之后你必须使用“。”,因为p [3]是一个对象,而不是一个指针。
答案 3 :(得分:3)
在...
MyClass* p = new myclass[10];
... p是指向MyClass对象数组的指针。 “指向数组的指针”必须首先进行删除。只要有指向数组的指针,p[n]
就会有效地为数组中的第n个元素提供引用,因此您实际上拥有MyClass&
。 那是为什么.
需要访问MyClass
成员ala p[n].member
,以及为什么在这种情况下指针特定的->
符号是错误的。 ...
请注意p->member
(对于任何成员)仍然有效且等效于p[0].member
,因此您只能使用它来访问数组中的第一个元素。我强烈建议你不要在编程上下文中使用它,其中'p'已知是指向数组的指针,因为它隐藏了p
是一个数组的事实。有时虽然你可以创建另一个指针 - 比如q
- 目的是引用单个数组元素 - 可能是也可能不是[0]
- 在这种情况下使用q->member
是公平的。像q
这样的变量也可用于对数组进行迭代。但是,有时你需要delete[] p;
- 所以你不会在事先改变p
之前......你不想忘记p[0]
地址或delete[] p;
将是未定义的行为(如果p
仍然指向数组中,则允许实现定义并恰好在Windows上,但不会是可移植的。)
答案 4 :(得分:2)
myclass *ptr;
ptr = new myclass(); // ptr points to a single object
ptr->doSomething(); // calls doSomething on the object _pointed to_
ptr = new myclass[10]; // ptr points to multiple objects
ptr->doSomething(); // calls doSomething on the first object _pointed to_
(ptr+1)->doSomething(); // calls doSomething on the second object _pointed to_
auto val = ptr[2]; // fetches a reference to the second _object_ to val.
val.doSomething(); // calls doSomething on the _object reference_ val.
换句话说,当索引数组以获取第n个元素时,你没有将指针提取到第n个元素,而是获取对实际对象的引用,需要使用.
语法访问其成员。
答案 5 :(得分:1)
考虑到
,也许考虑到这一点很有见地myclass obj;
auto p = &obj; // avoid `new` with plain pointers. That combination is
// safer replaced by unique_ptr or std::vector.
以下将全部有效并且是等效的:
p->setdata(5, 6);
(*p).setdata(5, 6);
p[0].setdata(5, 6);
0[p].setdata(5, 6);
显示[]
实际上是一个指针解除引用运算符,只需要额外的功能就可以将偏移量添加到普通的C数组中。
在C ++代码中使用C数组通常是个问题;您示例的明显替代方法是std::vector
:
std::vector<myclass> array(10);
此处,array[n]
可以像之前的p[n]
一样使用,但
array.at(n)
)for(auto& obj: array){...}
。