据我所知,你不能从一个方法中返回数组,因为你实际上是返回一个指向在方法作用域中创建的数据的指针,不能保证数据仍然在方法作用域之外的指针所指向的地址。
但它似乎对构造函数有效,因为这段代码每次运行时都打印为true。
class Vector3d {
public:
float* data_ptr;
public:
Vector3d(float values[3]) {
data_ptr = values;
}
};
int main(){
float arr[] = {3, 4, 5};
Vector3d vec = Vector3d(arr);
cout << (vec.data_ptr[0] == arr[0]) << endl;
}
我认为我的另一个选择是将成员变量变成数组而不是指针,并使用“复制”构造函数:
class Vector3d {
public:
float data_ptr[3];
public:
Vector3d(float values[3]) {
for (int i = 0; i < 3; i++) {
data_ptr[i] = values[i];
}
}
};
这是否意味着data_ptr[i]
和values[i]
现在是两个不同的值,存储在不同的内存地址中,或者这些变量共享一个内存位置?
2条答案
按热度按时间omqzjyyz1#
函数形参(包括构造函数形参)中的数组类型具有特殊的规则,这些规则使它的行为就像是在几乎所有情况下都使用as指针声明的一样。
所以
实际上是
所以,在第一个代码片段中,你只是将一个指向
arr
的指针值从main
存储到data_ptr
中。main
中的arr
一直存在到main
结束。所以你仍然可以访问它。当你访问data_ptr[i]
时,你实际上是在访问arr[i]
。在这段代码中没有复制数组。你只是在操作指针。如果你想让数组像其他类型一样有复制行为,那么就用
std::array
代替内置数组。std::array
的行为像任何标量或类类型,而内置数组有从C继承的奇怪行为。在第二个代码片段中,我们显式地将
arr
中的元素复制到一个新的数组data_ptr
中。data_ptr
数组与arr
数组不同,因为它们的生存期重叠,所以它们必须位于不同的地址。values
只是指向arr
的指针。i86rm4rw2#
(This忽略您的类由于某种原因不拥有内存的事实)。
不,除了表面上的,没有复制。我已经发明了自己的规则来处理(遗留的)c-数组。总是通过引用传递它们。(是的,你可以显式地通过引用传递c-数组)。
原因是这是编译器所看到的,添加
&
对编码者来说更清楚,换句话说,float[3]
作为参数是一个“谎言”,而float(&)[3]
不是。在现代代码中,只需使用
std::array<T, N>
,它精确地 Package 了T[N]
以获得预期的行为。std::array<T, N>&
将绑定,std::array<T, N>
将复制(这可能不是您想要的)。