繁体   English   中英

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

[英]Confusion on operator overloading and heap vs stack

我正在看以下教程: 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);
}

我对为什么这起作用感到困惑。 这不应该立即导致分段错误吗? 返回值在堆栈上,并且在所有这些函数终止时应将其删除。 为什么行得通? 我对堆栈和堆的理解不正确吗?

编辑:我基于此理解: 如何在C ++中通过引用返回类对象?

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

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

从根本上说,这与return 1;没有区别return 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 ++中为对象定义的按值返回。

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

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

如何工作中已经回答了什么是右值,左值,xvalues,glvalues和prvalues?

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

因此,每个cpu都有自己的调用约定。 欲了解更多详细信息,看看这个这个

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM