[英]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
:要查看会发生什么,请考虑
T
是Person
:
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.