簡體   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