c++ 这里有复印机吗

zujrkrfu  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(130)

据我所知,你不能从一个方法中返回数组,因为你实际上是返回一个指向在方法作用域中创建的数据的指针,不能保证数据仍然在方法作用域之外的指针所指向的地址。
但它似乎对构造函数有效,因为这段代码每次运行时都打印为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]现在是两个不同的值,存储在不同的内存地址中,或者这些变量共享一个内存位置?

omqzjyyz

omqzjyyz1#

函数形参(包括构造函数形参)中的数组类型具有特殊的规则,这些规则使它的行为就像是在几乎所有情况下都使用as指针声明的一样。
所以

Vector3d(float values[3])

实际上是

Vector3d(float* values)

所以,在第一个代码片段中,你只是将一个指向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的指针。

i86rm4rw

i86rm4rw2#

(This忽略您的类由于某种原因不拥有内存的事实)。
不,除了表面上的,没有复制。我已经发明了自己的规则来处理(遗留的)c-数组。总是通过引用传递它们。(是的,你可以显式地通过引用传递c-数组)。

#include<iostream>

using namespace std;

class Vector3dR {

    public:
        float* data_ptr;

    public:
        Vector3dR(float (&values)[3]) {
            data_ptr = &values[0];
        }
        
};

int main(){
    float arr[] = {3, 4, 5};
    Vector3dRef vec = Vector3dRef(arr);
    
    cout << (vec.data_ptr[0] == arr[0]) << endl;
}

原因是这是编译器所看到的,添加&对编码者来说更清楚,换句话说,float[3]作为参数是一个“谎言”,而float(&)[3]不是。
在现代代码中,只需使用std::array<T, N>,它精确地 Package 了T[N]以获得预期的行为。std::array<T, N>&将绑定,std::array<T, N>将复制(这可能不是您想要的)。

Vector3dR(std::array<float, 3>& values) {  // doesn't copy
            data_ptr = &values[0];
        }
        
};

int main(){
    std::array<float, 3> arr = {{3, 4, 5}};
    Vector3dRef vec = Vector3dRef(arr);

相关问题