C++ (->) 箭头运算符和 (.) 点运算符,类指针

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17716293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:22:47  来源:igfitidea点击:

(->) arrow operator and (.) dot operator , class pointer

c++classpointers

提问by lukai

In c++ we know that for a pointer of class we use (->) arrow operator to access the members of that class like here:

在 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;
}

Then I create a array of "myclass".

然后我创建了一个“myclass”数组。

p=new myclass[10];

but then, when I go to access myclassmembers through (->) arrow operator, I get following error

但是,当我myclass通过 (->) 箭头运算符访问成员时,出现以下错误

base operand of '->' has non-pointer type 'myclass'

but while I access class members through (.) operator it works. These things make me confused. Why for array of class I have to use (.) operator.

但是当我通过 (.) 运算符访问类成员时,它可以工作。这些事情让我很困惑。为什么对于类数组我必须使用 (.) 运算符。

回答by Opsenas

you should read about difference between pointers and referencethat might help you understand your problem.

您应该阅读指针和引用之间的区别,这可能有助于您理解您的问题。

In short, the difference is:
when you declare myclass *pit's a pointer and you can access it's members with ->, because ppoints to memory location.

简而言之,区别在于:
当您声明myclass *p它是一个指针时,您可以使用 访问它的成员->,因为p指向内存位置。

But as soon as you call p=new myclass[10];pstarts to point to array and when you call p[n]you get a reference, which members must be accessed using ..
But if you use p->member = smththat would be the same as if you called p[0].member = smth, because number in []is an offset from pto where search for the next array member, for example (p + 5)->member = smthwould be same as p[5].member = smth

但是一旦你调用p=new myclass[10];p开始指向数组并且当你调用时你p[n]会得到一个引用,哪些成员必须使用..
但是,如果您使用p->member = smth它,将与调用 相同p[0].member = smth,因为 number in[]是从p到 where 搜索下一个数组成员的偏移量,例如(p + 5)->member = smth将与p[5].member = smth

回答by TobiMcNamobi

Note that for a pointer variable x

请注意,对于指针变量 x

myclass *x;
  • *xmeans "get the object that x points to"
  • x->setdata(1, 2)is the same as (*x).setdata(1, 2)and finally
  • x[n]means "get the n-th object in an array".
  • *x意思是“得到 x 指向的对象”
  • x->setdata(1, 2)是一样的(*x).setdata(1, 2),最后
  • x[n]表示“获取数组中的第 n 个对象”。

So for example x->setdata(1, 2)is the same as x[0].setdata(1, 2).

因此,例如x->setdata(1, 2)x[0].setdata(1, 2).

回答by SGrebenkin

Because by using [] like p[3] you are already dereferencing the pointer to array + index shift. After that you have to use ".", since p[3] is an object, not a pointer.

因为通过像 p[3] 一样使用 [],您已经在取消引用指向数组 + 索引移位的指针。之后你必须使用“.”,因为 p[3] 是一个对象,而不是一个指针。

回答by Tony Delroy

After...

后...

MyClass* p = new myclass[10];

...p is a pointer to an array of MyClass objects. The "pointer to an array" thing has to be delt with first. Whenever you have a pointer to an array, p[n]effectively gives you a referenceto the nth element in the array, so you effectively have a MyClass&. That'swhy .is then needed to access MyClassmembers ala p[n].member, and why the pointer-specific ->notation is erroneous in this case....

...p 是指向 MyClass 对象数组的指针。必须首先删除“指向数组的指针”。每当您有一个指向数组的指针时,就会p[n]有效地为您提供数组中第 n 个元素的引用,因此您实际上拥有一个MyClass&. 这就是为什么.需要访问MyClass成员 ala p[n].member,以及为什么->在这种情况下特定于指针的符号是错误的......

Note that p->member(for any member) is still valid and equivalent to p[0].member, so you can only use it for accessing the first element in the array. I strongly recommend you don't use it at all whenever you're in a programmatic context where 'p' is known to be pointer to the array, as it hides the fact that pis an array. Sometimes though you may create another pointer - say q- with the purpose of refering to a single array element - may or may not be [0]- and in those situation's it's fair to use q->member. Variables like qmay be used for iteration over the array too. But, sometime you're going to need to delete[] p;- so you won't tend to change pbeforehands... you don't want to lose track of the p[0]address or delete[] p;will be Undefined Behaviour (which is allowed to be implementation defined and happens to be on Windows if pstill points within the array, but won't be portable).

请注意,p->member(对于任何成员)仍然有效并等效于p[0].member,因此您只能使用它来访问数组中的第一个元素。我强烈建议您在程序上下文中根本不要使用它,其中 'p' 已知是指向数组的指针,因为它隐藏p了数组的事实。有时虽然您可能会创建另一个指针 - 例如q- 目的是引用单个数组元素 - 可能会也可能不会[0]- 在这些情况下使用q->member. 变量 likeq也可用于对数组进行迭代。但是,有时您将需要delete[] p;- 因此您不会p事先更改...您不想忘记p[0]地址或delete[] p;将是未定义的行为(允许实现定义并且碰巧在 Windows 上,如果p仍然指向数组内,但不会是可移植的)。

回答by Joachim Isaksson

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.

In other words, when indexing the array to fetch the n'th element, you're not fetching a pointerto the n'th element, you're fetching a reference to the actual object, and the members of that need to be accessed using .syntax.

换句话说,当索引数组以获取第 n 个元素时,您不是获取指向第 n 个元素的指针,而是获取对实际对象的引用,并且需要访问该对象的成员使用.语法。

回答by leftaroundabout

Perhaps its insightful to consider that, given

也许考虑到这一点很有见地,鉴于

myclass obj;
auto p = &obj;  // avoid `new` with plain pointers. That combination is
               //  safer replaced by unique_ptr or std::vector.

the following will all work and are equivalent:

以下都将起作用并且是等效的:

p->setdata(5, 6);
(*p).setdata(5, 6);
p[0].setdata(5, 6);
0[p].setdata(5, 6);

Showing that []is really a pointer-dereferencing operator, just with the extra functionality that you can add offsets into a plain C-array.

表明[]它确实是一个指针取消引用运算符,只是具有可以将偏移量添加到普通 C 数组中的额外功能。

It's generally questionable to use C-arrays in C++ code; the obvious alternative to your example is std::vector:

在 C++ 代码中使用 C 数组通常是有问题的;您示例的明显替代方法是std::vector

std::vector<myclass> array(10);

Here, array[n]can be used much like previously p[n], but

在这里,array[n]可以像以前一样使用p[n],但是

  • You don't get any stupid pointer-ideas, because there are no pointers in the interface
  • You get proper automatic memory management, i.e. when the array goes out of scope it automatically deletes the objects and its memory
  • You can get bounds-checks if you want (array.at(n))
  • You can easily loop over the whole array, with (C++11) for(auto& obj: array){...}.
  • 你不会得到任何愚蠢的指针想法,因为接口中没有指针
  • 您将获得适当的自动内存管理,即当数组超出范围时,它会自动删除对象及其内存
  • 如果需要,您可以进行边界检查 ( array.at(n))
  • 您可以使用 (C++11) 轻松遍历整个数组for(auto& obj: array){...}