C++ 为结构(或类)行为数组赋值

C++ 为结构(或类)行为数组赋值,c++,arrays,memory-management,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++)

在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 + "]");
}
因此,在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;
    }
}
但是,我确实:

data[y].field1 = 2;
data[y].field2 = 3;
它确实有效

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

MyClass * d = &data[y];
d->field1 = 2;
d->field2 = 3;
我在打印输出时没有做任何更改。而上述工作

因此,当使用指向数据[y]的指针时,情况显然有所不同。但我找不到一个明确的答案。有人能解释为什么吗

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


PPS:我知道我没有在堆中分配这个数组。触摸要与之比较的主题的额外积分:)

您正在此处复制:

MyClass d = data[y];
d
的修改对
数据[y]
没有影响

取而代之的是引用:

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

d = someMyClassInstance;

将具有将
someMyClassInstance
的值分配给
数据[y]

的效果。您正在此处制作副本:

MyClass d = data[y];
d
的修改对
数据[y]
没有影响

取而代之的是引用:

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

d = someMyClassInstance;
将具有将
someMyClassInstance
的值分配给
数据[y]

的效果,如下所示:

    MyClass d = data[y];
    d.field1 = 2;
    d.field2 = 3;
无效,因为
d
现在是
数据[y]
的副本。如果你说的是
MyClass&d
,你会有一个(非常量)参考,你可以修改它,然后观察
数据中的这些变化,如下所示:

    MyClass d = data[y];
    d.field1 = 2;
    d.field2 = 3;
无效,因为
d
现在是
数据[y]
的副本。如果你说“代码> MyCype和D<代码>,你会有一个(非const)引用,你可以修改它,然后观察C++中的代码>数据> /COP> .< /P> < P>的变化,一个对象是一个存储区域,即内存区域。变量直接表示对象,除非它们明确限定为指向现有对象的指针或引用

当你写作时:

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

你想写:

MyClass &d = data[y];
        ^--- here
符号
&
表示
d
作为对象
data[y]
的参考,因此只要对象继续存在于最初表示为
data[y]
的存储区域内(即在该地址),您就可以使用
d
修改该对象

使用指针类似,但指针可以被重新存储以指向不同的对象,必须使用间接语法(<代码> *>代码>或<代码> ->代码>)来表示指向的对象。C++中的

< P>,对象是存储区域,即内存区域。变量直接表示对象,除非它们明确限定为指向现有对象的指针或引用

当你写作时:

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

你想写:

MyClass &d = data[y];
        ^--- here
符号
&
表示
d
作为对象
data[y]
的参考,因此只要对象继续存在于最初表示为
data[y]
的存储区域内(即在该地址),您就可以使用
d
修改该对象


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

哇,谢谢!答案很清楚。为了更好地了解这些行为,您有没有进一步的参考资料?例如,这是一个一维数组。如果我想要一个二维数组呢?在Java中,事情更容易掌握。但我坚持在C++中这样做。再次感谢!哇,非常感谢!答案很清楚。为了更好地了解这些行为,您有没有进一步的参考资料?例如,这是一个一维数组。如果我想要一个二维数组呢?在Java中,事情更容易掌握。但我坚持在C++中这样做。再次感谢!谢谢!我没有意识到我在复制。现在有道理了。非常感谢!我没有意识到我在复制。现在有道理了。