我正在看以下教程: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++?
您可以查看以下示例:
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;
一般情况下会发生以下情况:
b
的默认复制构造函数。复制构造函数将字段从其参数复制到'b'的实例。除了默认提供的浅拷贝之外,您始终可以实现自己的拷贝构造函数来执行其他操作。
Vec3f(const Ver3f &src)...
因此,您将获得一个新对象,其中所有字段都是从return语句中创建的字段中复制的。这是c ++中为对象定义的返回值。
如果通过指针或引用返回对象,结果将会不同。它会导致内存损坏。
Vec3f Vec3f::operator*(float scale) const {
return Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);
}
这使用了返回值,因此返回的是该行创建的类实例的值,而不是实例本身。
这与return 1;
基本上没有什么不同。返回值1,而不是包含该值的任何特定实例或类成员。与其他所有内容一样,实现有责任弄清楚如何完成代码所要求的内容 - 在这种情况下,确保存在一些实例以保持返回值具有适当的生命周期。
这是二进制乘法运算符,它将Vec3f
实例中的数据副本(乘以float scale
)返回到rvalue,供表达式的其余部分使用。
如何运作已经在What are rvalues, lvalues, xvalues, glvalues, and prvalues?得到了解答
另见https://en.cppreference.com/w/cpp/language/operator_arithmetic