对运算符重载和堆与堆栈的混淆
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;
没有什么不同。返回值 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;
通常会发生以下情况:
运算符重载实现将使用表示乘法的新参数构造 Ve3f 的新实例。
返回过程将使用参数中的构造对象调用
b
的默认复制构造函数。复制构造函数会将字段从其参数复制到"b"的实例。
您始终可以实现自己的复制构造函数来执行默认副本提供的浅层副本之外的其他操作。
Vec3f(const Ver3f &src)...
因此,结果您将获得一个新对象,其中包含从 return 语句中创建的字段复制的所有字段。这是 c++ 中为对象定义的按值返回。
如果通过指针或引用返回对象,结果会有所不同。这将导致内存损坏。
这是二进制乘法运算符,它将Vec3f
实例中的数据副本(乘以float scale
)返回到右值,以供表达式的其余部分使用。
这如何工作已经在什么是右值、左值、x值、gl值和prvalue中得到了答案?
另请参阅 https://en.cppreference.com/w/cpp/language/operator_arithmetic
因此,每个 CPU 都有自己的调用约定。有关更多详细信息,请查看此和此
基本上,返回值或返回值的地址被复制到寄存器中,例如 ARM 中的 R0 和 x86 中的 EAX,以便函数的调用方可以访问它。
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 在功能块中使用新运算符时存在于堆或堆栈上?
- 使用堆栈编译错误的 C++ 反向行没有运算符匹配操作数
- C++对自动(堆栈)指针使用运算符删除
- 如何修复 c++ 中重载加法运算符上的堆栈溢出
- 重载时获取堆栈溢出 >> 运算符函数是为类调用的。我需要进行哪些更改?
- 对运算符重载和堆与堆栈的混淆
- 使用条件运算符递归计算模板化值或函数时出现错误 C1202(堆栈溢出)
- C++ STL 关系运算符如何比较堆栈
- 堆栈类中的赋值运算符故障
- 分段错误(核心转储) 覆盖运算符时<<堆栈
- 堆栈的重载比较运算符
- 堆栈列表类的重载>>运算符
- 错误 C2244:"堆栈:<T>:运算符=":无法将函数定义与现有声明匹配
- Visual Studio 2008 运行时堆栈溢出警告,当运算符在所有路径上<递归时警告
- 检测对堆栈变量的调用delete(使用强制转换到指针运算符)