运算符重载和堆与堆栈混淆

时间:2019-03-07 22:40:08

标签: c++ memory-management operator-overloading heap-memory stack-memory

我正在看以下教程: 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++?

4 个答案:

答案 0 :(得分:3)

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

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

这与return 1;基本上没有区别。将返回 value ,而不是包含该值的任何特定实例或类成员。与几乎所有其他内容一样,实现的责任是弄清楚如何完成代码所要求的工作-在这种情况下,请确保存在某个实例以在适当的生存期内保存返回的值。

答案 1 :(得分: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 ++中为对象定义的按值返回。

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

答案 2 :(得分:0)

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

{p> 3 的工作原理已经在What are rvalues, lvalues, xvalues, glvalues, and prvalues?

中得到了解答。

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

答案 3 :(得分:-1)

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

基本上,将返回值或返回值的地址复制到a寄存器中,例如ARM中的R0和x86中的EAX,以便函数的调用者可以访问它。