将值分配给struct(或class)行为的数组

时间:2013-02-26 11:58:29

标签: c++ arrays memory-management

从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中你首先创建了Array,它默认具有所有空值,然后在第一个循环中创建一个新的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;
    }
}

所以,如果我理解正确,根据this StackOverflow question,我可以像上面的代码一样创建一个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;

打印输出时我没有改变任何内容。以上工作。

因此,当使用指向数据[y]的指针时,显然会有所不同。虽然我无法找到明确的答案。有谁能解释为什么?

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

PPS:我知道我没有在堆中分配这个数组。触及该主题的奖励积分与:)

3 个答案:

答案 0 :(得分:1)

你在这里复制:

MyClass d = data[y];

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

改为参考:

MyClass& d = data[y];

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

d = someMyClassInstance;

会将someMyClassInstance的值分配给data[y]

答案 1 :(得分:1)

此:

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

无效,因为d现在是data[y]的副本。如果你说MyClass& d,你就会有一个(非常量)引用,你可以修改它,然后在data中观察这些变化。

答案 2 :(得分:1)

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

当你写:

MyClass d = data[y];

声明类型为MyClass的变量,定义为表示堆栈中的对象,初始化来自对象data[y]; ddata[y]是不同的对象,因此修改d不会影响data[y]

你想写:

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

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

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