简体   繁体   English

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

[英]Confusion on operator overloading and heap vs stack

I'm looking at the following tutorial: http://www.videotutorialsrock.com/opengl_tutorial/animation/home.php 我正在看以下教程: http : //www.videotutorialsrock.com/opengl_tutorial/animation/home.php

This person has a vector class: 此人有一个向量类:

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;
};

With an example definition: 带有示例定义:

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

I'm confused on why this works. 我对为什么这起作用感到困惑。 Shouldn't this immediately cause a segmentation fault? 这不应该立即导致分段错误吗? The return value is on the stack and should get deleted upon termination of all of these functions. 返回值在堆栈上,并且在所有这些函数终止时应将其删除。 Why does it work? 为什么行得通? Is my understanding of stack vs heap incorrect? 我对堆栈和堆的理解不正确吗?

EDIT: I am basing my understanding from this: How to return a class object by reference in C++? 编辑:我基于此理解: 如何在C ++中通过引用返回类对象?

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

This uses return by value, so what is returned is the value of the class instance created by that line, not the instance itself. 这使用按值返回,因此返回的是该行创建的类实例的 ,而不是实例本身。

This is fundamentally no different from return 1; 从根本上说,这与return 1;没有区别return 1; . The value one is returned, not any particular instance or class member that contains that value. 返回 1,而不是包含该值的任何特定实例或类成员。 As with pretty much everything else, it's the implementation's responsibility to figure out how to accomplish what the code asks for -- in this case, ensuring that some instance exists to hold the returned value with an appropriate lifetime. 与几乎所有其他内容一样,实现的责任是弄清楚如何完成代码所要求的内容-在这种情况下,请确保存在某个实例以在适当的生存期内保存返回的值。

You can look in the following example: 您可以看以下示例:

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;

In general the following will happen: 通常,将发生以下情况:

  1. the operator overload implementation will construct a new instance of the Ve3f with the new arguments, representing multiplication. 运算符重载实现将使用新参数(表示乘法)构造Ve3f的新实例。

  2. the return procedure will call a default copy constructor of b with the constructed object in the argument. 返回过程将调用默认的b复制构造函数,并在参数中包含构造的对象。 The copy-constructor will copy fields from its argument to the instance of 'b'. 复制构造函数会将字段从其参数复制到“ b”的实例。

You can always implement your own copy constructor to do something else besides the shallow copy which the default one provides. 除了默认副本提供的浅表副本之外,您始终可以实现自己的副本构造函数以执行其他操作。

Vec3f(const Ver3f &src)...

So, as a result you will get a new objects with all fields copied from the one created at the return statement. 因此,结果是您将获得一个新对象,该对象的所有字段都从在return语句中创建的字段复制而来。 This is the return by value as defined in c++ for objects. 这是c ++中为对象定义的按值返回。

The result would be different if you returned the object by a pointer or a reference. 如果通过指针或引用返回对象,则结果将有所不同。 It will cause a memory corruption. 它将导致内存损坏。

That's the binary multiplication operator, and it's returning a copy of the data in the Vec3f instance, multiplied by float scale , into an rvalue for use by the rest of an expression. 那是二进制乘法运算符,它将Vec3f实例中的数据副本乘以float scale到一个rvalue中,供表达式的其余部分使用。

How that works is already answered in What are rvalues, lvalues, xvalues, glvalues, and prvalues? 如何工作中已经回答了什么是右值,左值,xvalues,glvalues和prvalues?

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

So, every cpu has it's own calling convention. 因此,每个cpu都有自己的调用约定。 For more detailed info look into this and this 欲了解更多详细信息,看看这个这个

Basically, the return value, or the address to the return value is copied to the a register like R0 in ARM and EAX in x86 so the caller of the function can access it. 基本上,返回值或返回值的地址被复制到一个寄存器中,例如ARM中的R0和x86中的EAX,因此函数的调用者可以访问它。

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

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