C++;添加2个3D向量将返回垃圾值 我对C++非常陌生,刚开始学习操作符重载。这是我的尝试 class Vector { public: float x=0,y=0,z=0; Vector(float x, float y, float z) :x(x),y(y),z(z) {} Vector(Vector& copy) :x(copy.x),y(copy.y),z(copy.z){ std::cout << "Copy Created" << std::endl;} //Testing if any new objects were created during the operator overloading process[For my purpose this should not be called as no new objects should be created except than the returned result of each operator] public: Vector& operator+(Vector& v1) //return this+v1 { Vector v(this->x+v1.x,this->y+v1.y,this->z+v1.z); return v; } Vector& operator-(Vector& v1) //return this-v1 { Vector v(this->x - v1.x, this->y - v1.y, this->z - v1.z); return v; } Vector& operator*(Vector& v1) //return this cross v1 { Vector v(this->y * v1.z-this->z * v1.y, -this->x * v1.z + this->z * v1.x, this->x * v1.y - this->y * v1.x); return v; } } std::ostream& operator<<(std::ostream& output, Vector& v) { output << v.x << "," << v.y << "," << v.z << std::endl; return output; } int main() { Vector v1(1, 2, 3), v2(4, 5, 6); Vector v3 = v1 + v2, v4 = v1 - v2, v5 = v1 * v2; std::cout << v3 << v4 << v5; return 1; } 类向量 { 公众: 浮动x=0,y=0,z=0; 向量(float x,float y,float z):x(x),y(y),z(z){ 向量(Vector©):x(copy.x),y(copy.y),z(copy.z){std::couty+v1.y,this->z+v1.z); 返回v; } 向量和运算符-(向量和v1)//返回this-v1 { 向量v(this->x-v1.x,this->y-v1.y,this->z-v1.z); 返回v; } 向量和运算符*(向量和v1)//返回此交叉v1 { 向量v(this->y*v1.z-this->z*v1.y,-this->x*v1.z+this->z*v1.x,this->x*v1.y-this->y*v1.x); 返回v; } } std::ostream&operator

C++;添加2个3D向量将返回垃圾值 我对C++非常陌生,刚开始学习操作符重载。这是我的尝试 class Vector { public: float x=0,y=0,z=0; Vector(float x, float y, float z) :x(x),y(y),z(z) {} Vector(Vector& copy) :x(copy.x),y(copy.y),z(copy.z){ std::cout << "Copy Created" << std::endl;} //Testing if any new objects were created during the operator overloading process[For my purpose this should not be called as no new objects should be created except than the returned result of each operator] public: Vector& operator+(Vector& v1) //return this+v1 { Vector v(this->x+v1.x,this->y+v1.y,this->z+v1.z); return v; } Vector& operator-(Vector& v1) //return this-v1 { Vector v(this->x - v1.x, this->y - v1.y, this->z - v1.z); return v; } Vector& operator*(Vector& v1) //return this cross v1 { Vector v(this->y * v1.z-this->z * v1.y, -this->x * v1.z + this->z * v1.x, this->x * v1.y - this->y * v1.x); return v; } } std::ostream& operator<<(std::ostream& output, Vector& v) { output << v.x << "," << v.y << "," << v.z << std::endl; return output; } int main() { Vector v1(1, 2, 3), v2(4, 5, 6); Vector v3 = v1 + v2, v4 = v1 - v2, v5 = v1 * v2; std::cout << v3 << v4 << v5; return 1; } 类向量 { 公众: 浮动x=0,y=0,z=0; 向量(float x,float y,float z):x(x),y(y),z(z){ 向量(Vector©):x(copy.x),y(copy.y),z(copy.z){std::couty+v1.y,this->z+v1.z); 返回v; } 向量和运算符-(向量和v1)//返回this-v1 { 向量v(this->x-v1.x,this->y-v1.y,this->z-v1.z); 返回v; } 向量和运算符*(向量和v1)//返回此交叉v1 { 向量v(this->y*v1.z-this->z*v1.y,-this->x*v1.z+this->z*v1.x,this->x*v1.y-this->y*v1.x); 返回v; } } std::ostream&operator,c++,operator-overloading,copy-constructor,C++,Operator Overloading,Copy Constructor,不确定,但我认为您得到的是垃圾值,因为您试图返回对本地堆栈值v的引用。在重载运算符的作用域结束后,“v”值可能会被程序的另一部分覆盖 可能的解决办法是: Vector& operator+(Vector& v1) //return this+v1 { return *new Vector(this->x+v1.x,this->y+v1.y,this->z+v1.z); } 操作员+、*和-通常返回副本而不是参考: Vector operator+(co

不确定,但我认为您得到的是垃圾值,因为您试图返回对本地堆栈值v的引用。在重载运算符的作用域结束后,“v”值可能会被程序的另一部分覆盖

可能的解决办法是:

Vector& operator+(Vector& v1) //return this+v1
{
    return *new Vector(this->x+v1.x,this->y+v1.y,this->z+v1.z);
}

操作员
+
*
-
通常返回副本而不是参考:

Vector operator+(const Vector& v1) const
  //^^ no &
                //^^ added const  
                                  //^^ added const
{
   Vector v(this->x+v1.x,this->y+v1.y,this->z+v1.z);
   return v;
}
您还应该将该方法声明为
const
,以便可以对常量向量调用
操作符+
。参数应取为
const
reference

有关运算符重载的更多详细信息,请参见此处:

在您的代码中,您返回了一个对局部变量的引用,这总是错误的。一个简化的例子是

int& foo() {
   int x = 0;
   return x;
}
当函数返回且调用者获得悬空引用时,局部变量
x
的生存期结束。使用该引用调用

如果确实要避免复制,则应重载复合运算符
+=
*=
-=
。他们需要就地执行操作,并且通常在修改后返回对
的引用。有关详细信息,请参见上面的链接


我在上面写了“应该”、“典型”和“常规”。操作符重载相当灵活,可以做最奇怪的事情。然而,惯例是从操作符
+
*
-
返回一个新值,并且返回对局部变量的引用总是错误的


最后但并非最不重要的一点是,我想提到的是,看到一个初学者代码应用了如此少的错误实践,这是令人耳目一新的。除了你的错误,我唯一要批评的是常量的正确性。默认情况下,生成方法和参数
const
。仅当您需要修改它们时,才将其设置为非常量。例如,您的
运算符根据您的代码,我建议将您的运算符更改为运算符+=-=和*=。它们非常适合你的目的。在每个操作结束时,返回*this。这意味着返回当前工作对象。例如:

vector& vector::operator+= (const vector& v) 
 { this->x += v.x;
   this->y += v.y;
   this->z += v.z;
   return *this; 
 }
并将运算符+作为双参数友元函数写入:

 vector operator+(const vector&v1, const vector&v2)
  { vector v3(v1);  // copy constructor
    v3 += v2;
    return v3;
  }

如果在编译器上显示警告,它应该告诉您正在返回对临时(本地)变量的引用。不要这样做,而是返回副本。运算符
+
*
-
应该返回一个值而不是引用。请参见此处:(注意,它是“应该”,这是传统的方式,原则上,这些操作符可以返回任何内容,但返回对本地的引用在任何情况下都是错误的)@你是对的,我确实打开了我的编译器的警告,它确实向我显示了警告,但当输出出现时,它立即消失了,所以我看不到:)它有助于将警告视为错误<代码>-Werror
和GCC感谢你为我工作。在看到你的答案后,我查阅了一篇关于动态内存与堆栈内存的教程,我了解了很多。每个小型教程网站都从未提出过这一点,它们会错误地显示正确输出的屏幕截图,这让我困惑了一段时间。细节中的魔鬼我猜:)这看起来像是大量内存泄漏的处方。谁将
删除
向量
?当您在分配的堆栈上调用
Vector
上的
operator+
时,思考会变得非常复杂,因为您需要跟踪哪些
Vector
是新的,哪些不是手动的。这不是一个好的解决方案。它使OPs代码编译没有错误,但它会导致问题。答案确实对我有用,但现在在阅读了你的评论后,我是否应该将其取消标记为已接受的答案?有更好的选择吗?尝起来有点变态但是。。。仍然有效:)谢谢你的初学者提示。它在所有地方添加常量,包括“复制构造函数”本身的向量(constvector&v),最终解决了这个问题。我将对常量修饰符做更多的研究,以便更好地学习practices@RVISHAL仅添加
const
不会解决此问题!请注意,未定义的行为意味着您的代码是错误的,但不一定在编译过程中得到任何警告或错误。当您运行具有UB的代码时,它看起来可以工作,但它仍然是错误的。您需要修复返回对局部变量的引用@RVISHAL缺少的
const
会在其他代码中产生问题,而不是在你的代码中(除非我遗漏了什么),我已经更改了代码。我删除了只返回值的返回引用,但我不想编辑我的问题,希望将来看到这篇文章的人能够理解我的错误,并通过阅读您的answer@RVISHAL这是正确的方法。您不应该在问题中修复代码中的问题(除非它与实际问题完全无关)。问题是针对坏代码的,固定代码是针对答案的。