创建类数组时 -> 的基操作数存在非指针类型错误

问题描述 投票:0回答:2

我想了解为什么基操作数

->
在与指针一起使用时在某些情况下有效,而在其他情况下无效。

当我收到此错误时,我意识到我需要使用

.
而不是
->
。我试图理解为什么当我将指针作为数组元素引用为
.
时需要
p[i].somefunct()
,而当我直接将指针引用为
->
时需要
(p+i)->somefunct()

我编写了一个示例程序来说明这两种方法,并想知道是否有更有经验的人可以解释这种 C++ 行为。

我也有兴趣了解是否有更好的方法来创建、访问和销毁指向存储在堆上的类的指针数组。

#include <iostream>
using namespace std;

class KClass {
public:
    int x;
    KClass(){};
    ~KClass(){};
    int getx(){ return x; }
    void setx(int data){ x = data; return; }
};

int main()
{
    //use the heap to create an array of classes
    KClass *pk = new KClass[3]; //array of 3 pointers
    KClass *pk1 = new KClass[3]; //array of 3 pointers
    //do something
    for (int i = 0; i < 3; i++){
        (pk+i)->setx(i);
        cout << "(pk+" << i << ")->getx(): " << (pk+i)->getx() << endl;
    }
    cout << endl;
    for (int i=0;i<3;i++){
        //does not compile: pk1[i]->setx(i);
        //why is different syntax required when I access pk1 as an element of an array?
        pk1[i].setx(i);
        cout << "pk1[" << i << "].getx(): " << pk1[i].getx() << endl;
    }
    delete [] pk;
    delete [] pk1;
    pk = nullptr;
    pk1 = nullptr;

    getchar();
    return 0;
}
c++ arrays class
2个回答
1
投票

区别非常简单。

p[i]
*(p + i)
完全相同。完全一样,以至于
i[p]
是一种有效的(尽管超级混乱)编写数组订阅的形式。

因此,当您使用

p[i]
表单时,您已经取消引用结果,因此您可以通过
.
成员访问来访问成员。

如果您使用

(p + i)
而不取消引用,则需要通过
->
访问运算符访问成员,因为您正在处理指针。

只是一个重述 -

->
只不过是方便的快捷方式。每当您写类似
a->x
的内容时,您始终可以将其写为
(*a).x


0
投票

另一个答案解释了为什么

(p + i)
p[i]
不同,但它似乎仍然缺少一些东西。您将数组称为“指向类的指针数组”。这是不准确的。

new KClass[3]
不会创建指针数组。它创建一个对象数组。

如果你想创建一个指针数组,你可以使用

new KClass * [3]

记住

p
是指向数组本身的指针。
(p + i)
是指向数组元素的指针。但该元素本身不一定是指针。它与
int
数组的工作方式相同。如果您实际上有一个指针数组,那么要访问对象本身,您将需要两次取消引用。
p[i]->somefunct()
(**(p + i)).somefunct()

© www.soinside.com 2019 - 2024. All rights reserved.