关于运算符重载和堆与堆栈的混淆

问题描述 投票:0回答:4

我正在看以下教程:http://www.videotutorialsrock.com/opengl_tutorial/animation/home.php

这个人有一个矢量类:

class Vec3f {
private:
    float v[3];
public:
    Vec3f();
    Vec3f(float x, float y, float z);

    float &operator[](int index);
    float operator[](int index) const;

    Vec3f operator*(float scale) const;
    Vec3f operator/(float scale) const;
    Vec3f operator+(const Vec3f &other) const;
    Vec3f operator-(const Vec3f &other) const;
    Vec3f operator-() const;

    const Vec3f &operator*=(float scale);
    const Vec3f &operator/=(float scale);
    const Vec3f &operator+=(const Vec3f &other);
    const Vec3f &operator-=(const Vec3f &other);

    float magnitude() const;
    float magnitudeSquared() const;
    Vec3f normalize() const;
    float dot(const Vec3f &other) const;
    Vec3f cross(const Vec3f &other) const;
};

通过示例定义:

Vec3f Vec3f::operator*(float scale) const {
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);
}

我很困惑为什么这样做。这不应该立即导致分段错误吗?返回值在堆栈上,并应在所有这些函数终止时删除。它为什么有效?我对堆栈与堆的理解不正确吗?

编辑:我基于这个理解:How to return a class object by reference in C++?

c++ memory-management operator-overloading heap-memory stack-memory
4个回答
1
投票

您可以查看以下示例:

Vec3f Vec3f::operator*(float scale) const {
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);
}

Vec3f a(1,2,3);
Vec3f b;
b = a * 2;

一般情况下会发生以下情况:

  1. 运算符重载实现将使用新参数构造Ve3f的新实例,表示乘法。
  2. 返回过程将使用参数中的构造对象调用b的默认复制构造函数。复制构造函数将字段从其参数复制到'b'的实例。

除了默认提供的浅拷贝之外,您始终可以实现自己的拷贝构造函数来执行其他操作。

Vec3f(const Ver3f &src)...

因此,您将获得一个新对象,其中所有字段都是从return语句中创建的字段中复制的。这是c ++中为对象定义的返回值。

如果通过指针或引用返回对象,结果将会不同。它会导致内存损坏。


4
投票
Vec3f Vec3f::operator*(float scale) const {
    return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);
}

这使用了返回值,因此返回的是该行创建的类实例的值,而不是实例本身。

这与return 1;基本上没有什么不同。返回值1,而不是包含该值的任何特定实例或类成员。与其他所有内容一样,实现有责任弄清楚如何完成代码所要求的内容 - 在这种情况下,确保存在一些实例以保持返回值具有适当的生命周期。


0
投票

这是二进制乘法运算符,它将Vec3f实例中的数据副本(乘以float scale)返回到rvalue,供表达式的其余部分使用。

如何运作已经在What are rvalues, lvalues, xvalues, glvalues, and prvalues?得到了解答

另见https://en.cppreference.com/w/cpp/language/operator_arithmetic


-1
投票

所以,每个cpu都有自己的调用约定。有关更详细的信息,请查看thisthis

基本上,返回值或返回值的地址被复制到ARM中的R0和x86中的EAX等寄存器,因此函数的调用者可以访问它。

© www.soinside.com 2019 - 2024. All rights reserved.