简体   繁体   English

C++ 指针和 C 样式数组初始化

[英]C++ Pointers and C-style array initialization

Long time java programmer here, new to C++.长期 java 程序员在这里,C++ 新手。 I have been working with C-style "traditional" arrays (similar to arrays in java).我一直在使用 C 风格的“传统”arrays(类似于 java 中的 arrays)。 I understand in C++ we can create a simple array as follows:我了解在 C++ 中,我们可以创建一个简单的数组,如下所示:

Person people[3];

The contents of this array is essentially uninitialized junk values.这个数组的内容本质上是未初始化的垃圾值。 When I print out the contents of each element in the array, I (believe) am getting the memory address of each element.当我打印出数组中每个元素的内容时,我(相信)得到每个元素的 memory 地址。

for(int i = 0; i < 3; i++){std::cout << &person[i] << std::endl;}

Results:结果:

//Note, I get different results here when I use an enhanced for loop vs an iterator for loop. Weird.
00EFFB6C
00EFFBA8
00EFFBE4

Now, here is the part I have failed to get a clear explanation on.现在,这是我未能得到明确解释的部分。 I create a pointer to one of the elements in the array.我创建了一个指向数组中元素之一的指针。 I then ask for some value back from that pointer.然后我要求从该指针返回一些值。 In java, I would expect to get a null pointer, but in C++, that is not happening.在 java 中,我希望得到一个 null 指针,但在 C++ 中,这不会发生。

Instead, I get the default value, as though this element is initialized:相反,我得到了默认值,就好像这个元素被初始化了:

Person* person1Ptr = &people[0];//Points to an uninitialized value
std::cout << person1Ptr->getFirstName() << std::endl;//Output: "Default First Name", expected nullptr

When I try to get the first name of an element using a reference, this doesn't work (presumably because the value doesn't exist).当我尝试使用引用获取元素的名字时,这不起作用(可能是因为该值不存在)。

Full paste of code: https://pastebin.com/cEadfJhr代码全贴: https://pastebin.com/cEadfJhr

From my research, C++ does NOT fill arrays with objects of the specified type automagically.根据我的研究,C++ 不会自动用指定类型的对象填充 arrays。

How is my person1Ptr returning a value?我的 person1Ptr 如何返回值?

I believe the problem stems from this misconception:我认为问题源于这种误解:

From my research, C++ does NOT fill arrays with objects of the specified type automagically.根据我的研究,C++ 不会自动用指定类型的对象填充 arrays。

C++ objects have value semantics. C++ 对象具有值语义。 Defining a local variable of type T concretely creates a unique instance of that type, it is not a handle to a potential T .定义T类型的局部变量具体创建该类型的唯一实例,它不是潜在T的句柄。 The expression Foo f;表达式Foo f; is conceptually equivalent to the Java expression Foo f = new Foo();概念上等同于 Java 表达式Foo f = new Foo(); . . Additionally, value semantics means assignment usually implies a copy.此外,值语义意味着赋值通常意味着副本。 The C++ expression Foo f; Foo g = f; C++ 表达式Foo f; Foo g = f; Foo f; Foo g = f; is conceptually equivalent to the Java expression Foo f = new Foo(); Foo g = f.Clone();概念上等同于 Java 表达式Foo f = new Foo(); Foo g = f.Clone(); Foo f = new Foo(); Foo g = f.Clone(); . .

In the case of an array, defining a local variable Foo f[3];在数组的情况下,定义一个局部变量Foo f[3]; immediately creates three instances of Foo as elements of the f array.立即创建三个Foo实例作为f数组的元素。 Your misconception may come from the fact that creating an object in C++ does not imply that it has been initialized.您的误解可能来自这样一个事实,即在 C++ 中创建 object 并不意味着它已被初始化。 An object can exist in an uninitialized state. object 可以存在于未初始化的 state 中。 For example int i;例如int i; create an int object identified by i but its value is indeterminate.创建一个由i标识的int object 但其值不确定。 In the case of int i[3];int i[3]; you would have an array of three int each with indeterminate values.您将拥有一个由三个int组成的数组,每个 int 具有不确定的值。

The rules for initialization are very complicated in C++. C++中的初始化规则非常复杂。 In the case of Person people[3];Person people[3]; you have an array that is default initialized .你有一个默认初始化的数组。

You are initializing an object of type Person[3] .您正在初始化Person[3]类型的 object 。 According to default initialization rules:根据默认初始化规则:

if T is an array type, every element of the array is default-initialized;如果 T 是数组类型,则数组的每个元素都是默认初始化的;

That means each Person gets its own default initialization.这意味着每个Person都有自己的默认初始化。 To see what happens, consider that T is Person :要查看会发生什么,请考虑TPerson

if T is a class type, the constructors are considered and subjected to overload resolution against the empty argument list.如果 T 是 class 类型,则考虑构造函数并对空参数列表进行重载决议。 The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object;调用选择的构造函数(默认构造函数之一)为新的 object 提供初始值;

So each Person 's default constructor will be called to initialize that element.因此将调用每个Person的默认构造函数来初始化该元素。 You end up with Person people[3];你最终会得到Person people[3]; defining three default constructed Person objects with default initial values.定义三个具有默认初始值的默认构造的Person对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM