0

从Java我习惯了我可以做到这一点:

public class SomeClass {
    public int field1;
}

SomeClass[] data = new SomeClass[10];
for (int i = 0; i < 10; i++) {
    data[i] = new SomeClass(); 
    SomeClass d = data[i];
    d.field1 = 10;
}

for (int i = 0; i < 10; i++) {
    SomeClass d = data[i];
    System.out.println("Value of data [" + i + "] is [" + d.field1 + "]");
}

这将正常工作,打印:

Value of data [0] is [10]
Value of data [1] is [10]
... etc

因此,在 Java 中,您首先创建一个数组,默认情况下它具有所有空值,然后在第一个循环中,我创建一个新的 SomeClass 并将其分配给数组中的一个槽。如果你不这样做,你会得到一个 NullPointerException。

一切都好。

问题: 我尝试在 C++ 中做同样的事情。我有一个失败的例子和一个有效的例子。但我不确定它为什么起作用(或不起作用,取决于你选择的例子)。谁能详细说明?

首先,失败的代码:

int main(int argc, char **argv) {
    MyClass data[10];
    for (int y = 0; y < 10; y++) {
        MyClass d = data[y];
        cout << "INITIALLY (garbage): [" << d.field1 << ", " << d.field2 << "] " << endl;
        // assign values
        d.field1 = 2;
        d.field2 = 3;
    }

    // print out data of first 10
    cout << "Printing out data after initialization" << endl;
    for (int y = 0; y < 10; y++) {
        MyClass d = data[y];
        cout << "[" << d.field1 << ", " << d.field2 << "] " << endl;
    }
}

因此,如果我理解正确,根据这个 StackOverflow 问题,我可以像在上面的代码中那样创建一个 Struct 数组。

我注意到的是,如果我不使用:

MyClass d = data[y];
d.field1 = 2;
d.field2 = 3;

但相反,我这样做:

data[y].field1 = 2;
data[y].field2 = 3;

它确实有效。

但是,如果我坚持使用单独的值,我仍然可以通过以下方式使其工作:

MyClass * d = &data[y];
d->field1 = 2;
d->field2 = 3;

我在打印输出时没有改变任何东西。以上工作。

因此,当使用指向 data[y] 的指针时,情况显然有所不同。不过,我找不到明确的答案。任何人都可以解释为什么?

如果这个问题是重复的,很抱歉,我在“为什么”部分找不到真正的答案。代码片段对我来说并不总是足够的;)

PPS:我知道我没有在堆中分配这个数组。触摸该主题以进行比较的奖励积分:)

4

3 回答 3

1

您正在这里制作副本:

MyClass d = data[y];

d对没有影响的修改data[y]

取而代之的是参考:

MyClass& d = data[y];

现在d指的是元素data[y]。请注意,在 C++ 中,引用的行为类似于别名。您不能重新分配它。例如

d = someMyClassInstance;

将具有分配 to 的值的someMyClassInstance效果data[y]

于 2013-02-26T12:01:49.293 回答
1

这:

    MyClass d = data[y];
    d.field1 = 2;
    d.field2 = 3;

没有效果,因为d现在是data[y]. 相反,如果您说MyClass& d,您将有一个(非常量)引用,您可以对其进行修改,然后观察data.

于 2013-02-26T12:01:59.407 回答
1

在 C++ 中,对象是一个存储区域- 即内存区域。变量直接表示对象,除非它们被明确限定为指向现有对象的指针或引用。

当你写:

MyClass d = data[y];

您正在声明一个类型的变量MyClass,将其定义为表示堆栈上的一个对象,并从该对象初始化data[y]它;d并且data[y]是单独的对象,因此修改d不会影响data[y].

你想写:

MyClass &d = data[y];
        ^--- here

& 符号&表示对对象d引用data[y],因此只要一个对象继续存在于data[y]最初表示的存储区域内(即在该地址处),您就可以使用d该对象来修改该对象。

使用指针是类似的,但由于指针可以重新定位以指向不同的对象,因此您必须使用间接语法(*->)来表示它们指向的对象。

于 2013-02-26T12:07:22.900 回答