c++ - 如何正确返回类成员数组作为返回参数

标签 c++ arrays pointers

我对如何使用返回参数从类中获取多个 float 组感到困惑。这是一个简化的示例。

class Points
{
    private:
        float *x;
        float *y;
        float *z;
    public:
        void getCoordinates (float *retx, float *rety, float *retz);
}

void Points:: getCoordinates (float *retx, float *rety, float *retz)
{
    retx=x;
    rety=y;
    retz=z;
}

当我在函数内部进行赋值时,指针值匹配。但是,一旦我离开该功能,这些值就会发生变化。指针的范围是否受到某种限制?

基于 How to properly return an array (class member) in C++? ,我认为不应该是这样。讨论表明,不仅可以传递指针,而且通过指针对内存的更改将影响类的原始实例。正是我希望指针如何工作。

我尝试过的一种解决方法是使用 memcpy

void Points::getCoordinates (float *retx, float *rety, float *retz)
 {
memcpy(retx, x, sizeof(float)*numPoints);
memcpy(rety, y, sizeof(float)*numPoints);
memcpy(retz, z, sizeof(float)*numPoints);   
}

这也符合我的要求。这种方法的缺点是我需要在调用函数中分配正确数量的内存,而且我使用的内存比我认为需要的多。

最佳答案

However, the values change as soon as I leave the function. Is the scope of the pointer somehow limited?

这是应该的。

考虑这段代码:

int f(int a) { a = 20; }

int x = 10;
f(x);

当您调用f 时,会在堆栈上创建一个位置,其中放置x (10) 中的值。然后,这个地方被命名为a,并为a执行函数,具有x的值。如果您修改 a(如上面的代码),x 不会被修改,因为 x 是一个不同的变量。

现在,考虑当 a 是一个指针时会发生什么:

int g(int *a) { a = nullptr; }
int *b = new int{10};
g(b);

这里,在堆栈上为a 创建的值是一个内存地址。如果你修改地址本身(如果你做a = nullptr;),类似于上面的情况,b不受影响,只有a (即更改仅在函数体内有效)。

您可以修改a 指向的地址 处的值。虽然 ba 是不同的变量,但是当您调用 g(b) 时,两个变量(尽管不同)将包含相同的内存地址。因此,如果您更改 a 指向的地址处的值,您实际上是在向客户端代码返回一个值(您并不是真正返回它,但客户端代码可以访问它, 通过取消引用 b).

代码:

int g(int *a) { *a = 20; } // assign value to memory pointed to, by a
int *b = new int{10};
g(b); // a and b will point to the same value
assert(*b == 20); // evaluates to true

这是使用输出参数的C 风格。在 C 中,输出参数是一个保存地址的参数,因此修改该地址的值允许客户端代码访问该地址(如我上面的示例)。

在你的具体情况下,你的代码可以这样写(但可能不应该——见下文):

void Points::getCoordinates (float **retx, float **rety, float **retz)
{
    *retx=x;
    *rety=y;
    *retz=z;
}

每个参数都有一个额外的间接级别(即如果你想让你的输出参数保存一个 float 的地址,你必须将一个指向该地址的指针作为参数——即一个双指针,或一个指向一个指向 float 的指针)。

为什么不应该:

C++ 引入了引用,它允许将地址视为对象本身。 因此,对于 C++,您的代码可能如下所示:

void Points::getCoordinates (float *&retx, float *&rety, float *&retz)
{
    retx=x;
    rety=y;
    retz=z;
}

更好的是,在 C++ 中,您的代码可能应该如下所示(不确定这对您的代码/代码库是否可行):

struct Point3d { float x, y, z; }
Point3d Points::getCoordinates() const { return Point3d{ x, y, z }; }

关于c++ - 如何正确返回类成员数组作为返回参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24018462/

相关文章:

c++ - typedef 以下类型 : Pointer to a member function Fof "any" class having a member function F

c++ - 在公共(public)场合使用 X::func

c - 在 C 中使用指针打印数组时出现问题

Java:一个构造函数或方法将接受数组或集合或列表或......?

java - BufferedImage 图像指针数据作为 C 函数的 JNI 参数

c++ - RPC 身份验证

C++ 如何使用 std::sort 在 C++ 中对对象数组进行排序

ios - 二维数组的数据结构

有人可以帮我找到导致段错误(核心转储)的错误吗?

c - 通过 CONTEXT.Ebx+8 指向 baseAddress 的指针