重载问题

问题描述 投票:3回答:2

我正在尝试创建一组类来处理复数。我已经看到已经有一组复杂数字的类,但因为我正在学习C ++,我认为创建一个基本实现是个好主意。当我试图重载运算符“/”时出现问题。我遇到了段错误,我无法理解问题是否是我执行的部门:

complex.hpp:

#include <iostream>
#include <cstdlib>

class Complex {
  float real;
  float imm;
public:
  Complex(float new_real = 0,float new_imm = 0) {this->real = new_real;this->imm = new_imm;}
  void set(float new_real,float new_imm) {this->real = new_real; this->imm = new_imm;}
  float get_real(void) const { return this->real;}
  float get_imm(void) const { return this->imm;}
  Complex conj(void) const {Complex tmp; tmp.set(this->real,-1.0 * this->imm); return tmp;}
  friend std::ostream& operator<<(std::ostream& os, const Complex& cpx) {os << "Real: " << cpx.real << " Imm: " << cpx.imm << std::endl; return os; }
  friend Complex operator*(const Complex& lhs,const Complex& rhs);
  friend Complex operator+(const Complex& lhs,const Complex& rhs);
  friend Complex operator+(const Complex& lhs,const float& rhs);
};

complex.cpp:

#include "complex.hpp"


Complex operator*(const Complex& lhs,const Complex& rhs)
{
  float real_part = (lhs.real * rhs.real) - ( lhs.imm * rhs.imm);
  float imm_part = (lhs.real * rhs.imm) + ( lhs.imm * rhs.real);
  Complex result;
  result.set(real_part,imm_part);
  return result;
}

Complex operator+(const Complex& lhs,const Complex& rhs)
{
  float real_part = lhs.real + rhs.real;
  float imm_part = lhs.imm + rhs.imm;
  Complex result;
  result.set(real_part,imm_part);
  return result;
}

Complex operator+(const Complex& lhs,const float& rhs)
{
  float real_part = lhs.real + rhs;
  float imm_part = lhs.imm;
  Complex result;
  result.set(real_part,imm_part);
  return result;
}

Complex operator/(const Complex& lhs,const Complex& rhs)
{
  Complex numerator(0,0);
  numerator = rhs * rhs.conj();

  Complex denominator(0,0);
  denominator = lhs * rhs.conj();

  Complex result;
  float real_numerator = numerator.get_real();
  result = denominator / real_numerator;
  return result;
}

Complex operator/(const Complex& lhs,const float& rhs)
{
  float real_part = lhs.get_real() / rhs;
  float imm_part = lhs.get_imm() / rhs;
  Complex result;
  result.set(real_part,imm_part);
  return result;
}

2复数之间除法的整体思想是将分子的共轭的分子和分母相乘,以便在分子上只有一个实数。只是为了说清楚:

(a + ib)/(c + id)=((a + ib)/(c + id))*((c-id)/(c-id))=((a + ib)*(c - id))/(c ^ 2 + d ^ 2)

现在当我尝试这样做时:

main.cpp:

int main(int argc, char *argv[])
{
  Complex x(4,8);
  Complex y(3,7);
  Complex result = x / y;
  result = x / 6;
  return 0;
}

我得到了这个段错误,我不明白:

(gdb) break main
Breakpoint 2 at 0x401c56: file equalization_main.cpp, line 49.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
`/home/campiets/workspace/frontend/dfe_equalizer_fe/dev/view/src_c/test' has changed; re-reading symbols.
Starting program: /home/campiets/workspace/frontend/dfe_equalizer_fe/dev/view/src_c/test 

Breakpoint 2, main (argc=1, argv=0x7fffffffbf08) at equalization_main.cpp:49
49    Complex x(4,8);
(gdb) n
50    Complex y(3,7);
(gdb) n
51    Complex result = x / y;
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x0000000000401e64 in Complex::Complex (this=<error reading variable: Cannot access memory at address 0x7fffff3feff8>, new_real=<error reading variable: Cannot access memory at address 0x7fffff3feff4>, 
    new_imm=<error reading variable: Cannot access memory at address 0x7fffff3feff0>) at complex.hpp:38
38    Complex(float new_real = 0,float new_imm = 0) {this->real = new_real; this->imm = new_imm;}

有任何想法吗 ?

c++ segmentation-fault complex-numbers
2个回答
5
投票
Complex operator/(const Complex& lhs,const Complex& rhs)
{
  ...
  Complex denominator...;
  ...
  float real_numerator = ...;
  result = denominator / real_numerator;
  ...
}

这是无限递归。

由于编译器没有看到operator/(const Complex &lhs, const float &rhs),它将float参数转换为Complex,因此你得到递归。

最简单的解决方案是在operator/(const Complex &lhs, const float &rhs)之前声明或定义operator/(const Complex &lhs, const Complex &rhs)

不过,我的偏好是将运算符实现为类成员。这样可以生成更简单的源代码并解决问题。


3
投票

功能

Complex operator/(const Complex& lhs,const Complex& rhs) { ... }

导致堆栈溢出,因为该行

result = denominator / real_numerator;

最终被解释为:

result = denominator / Complex(real_numerator);

您可以通过定义或声明来解决该问题

Complex operator/(const Complex& lhs, const float& rhs)

在它之前。

如果您更改要使用的代码:

Complex operator/(const Complex& lhs,const float& rhs)
{
   return Complex(lhs.get_real()/rhs, lhs.get_imm()/rhs);
}

Complex operator/(const Complex& lhs,const Complex& rhs)
{
   ...
}

你的程序会正常工作。


关于简化上述operator/功能的建议。

如果添加以下成员函数

float magnitude_square() const { return (real*real + imm*imm); }

然后你可以使用

Complex operator/(const Complex& lhs,const Complex& rhs)
{
   return (lhs * rhs.conj())/rhs.magnitude_square());
}
© www.soinside.com 2019 - 2024. All rights reserved.