操作员=用双指针超载用于分数数学

operator= overloading with double pointers for fraction math

本文关键字:用于 数数 超载 指针 操作员      更新时间:2023-10-16

最初,我的实验室通过了三个参数:addfractionJesser( *lfrac, *rfrac,** resfrac);但是我发现我无法通过三个论点。我必须将其更改为** resfrac = addfractionJesser( *lfrac, *rfrac);现在我遇到问题。我知道我的指针和双重指针不在某个地方的范围之外,但我无法发现哪里。调试器指向第二行的问题:

FractionJesseR& FractionJesseR::operator=(const FractionJesseR& arg) {
  num = arg.num;
  denom = arg.denom;
  return *this;
}

命名为:

FractionJesseR& addMenu(FractionJesseR* lFrac, FractionJesseR* rFrac) {
  int option;
  FractionJesseR** resFrac = new FractionJesseR*();
......
    case 2:
      cout << "Calling add() --nn";
      **resFrac = addFractionJesseR(*lFrac, *rFrac);
      break;
    ......

** resfrac = addfractionJesser(*lfrac,*rfrac);最初是AddFractionJesser( *lfrac, *rfrac,** resfrac);

命名为:

void displayMenu() {
  int option;
  FractionJesseR *lFrac = nullptr;
  FractionJesseR *rFrac = nullptr;
  FractionJesseR *resFrac = nullptr;
......
    case 2:
      cout << "  Adding Option --nn";
      if (lFrac == nullptr && rFrac == nullptr) {
        cout << "    Not a proper call as no Fractions are available!nn";
      }
      else {
        *resFrac = addMenu(lFrac, rFrac);
      }
      break;

*resfrac = addMenu(lfrac,rfrac)最初是AddMenu(lfrac,rfrac,&amp; resfrac)

(是的,我确实在所有指示器上都拨打了删除,我仍然是新手堆叠溢出并学会仅张贴相关代码的片段),我需要帮助将我指向正确的方向。我认为我的指针从AddMenu或DisplayMenu的某个地方出现了范围...也许我在删除了双重指针错误?

任何帮助将不胜感激!

编辑:

FractionJesseR& addFractionJesseR(FractionJesseR& lFrac, FractionJesseR& rFrac) {
  int n = 0;
  int d = 0;
  FractionJesseR *resFrac = nullptr;
 // Adding the fractions
 n = (&lFrac)->getNum() * (&rFrac)->getDenom() + (&lFrac)->getDenom() *
    (&rFrac)->getNum();
  d = (&lFrac)->getDenom() * (&rFrac)->getDenom();
  resFrac = new FractionJesseR(n / gcd(n, d), d / gcd(n, d));
  if (d < 0) {
    d = -d;
    n = -n;
  }
  return *resFrac;
}

您在内存管理方面遇到问题。

我假设您正在使用某种版本的Visual Studio。调试器通常会标记要执行的下一行,因此您会在

上崩溃
num = arg.num;

这是因为this为null,因为

FractionJesseR** resFrac = new FractionJesseR*();

在免费商店(不寻常)上分配指针,并用0(由于括号)初始化它。这个:

**resFrac

首先放电resFrac,给出一个空指针,然后您再次解除。删除无效指针是未定义的行为。在您的情况下,它会在第一个语句中导致分配运算符的崩溃。

明显的解决方案是停止使用指针和手动内存管理。充其量,使用对象:

FractionJesseR resFrac
// ...
resFrac = addFractionJesseR(*lFrac, *rFrac);

最坏的情况,使用智能指针:

auto resFrac = std::make_unique<FractionJesseR>();
// ...
*resFrac = addFractionJesseR(*lFrac, *rFrac);

您不想做的事情(除非您被迫这样做是因为这是一项任务,在这种情况下,我会质疑动机):

auto resFrac = new FractionJesseR;
// ...
*resFrac = addFractionJesseR(*lFrac, *rFrac);
// ...
delete resFrac;

addFractionJesseR()正在返回对免费商店分配的值的引用。您要在哪里删除它?每个new都必须与delete匹配。

如果您真的想要一个手动内存管理的示例,则不应混合指针和参考:

FractionJesseR* addFractionJesseR(FractionJesseR* a, FractionJesseR* b)
{
    auto n = a->getNum() * b->getDenom() + a->getDenom() * b->getNum();
    auto d = a->getDenom() * b->getDenom();
    if (d < 0)
    {
        d = -d;
        n = -n;
    }
    return new FractionJesseR(n / gcd(n, d), d / gcd(n, d));
}
FractionJesseR* addMenu(FractionJesseR* a, FractionJesseR* b)
{
    // ...
    FractionJesseR* resFrac = addFractionJesseR(a, b);
    // ...
    return resFrac;
}
void displayMenu()
{
    // ...
    FractionJesseR *resFrac = addMenu(lFrac, rFrac);
    // ...
    delete resFrac;
}

请注意,在addFractionJesseR()中分配的指针返回到addMenu(),该指针将其返回到displayMenu(),该指针将其删除。