gpt4 book ai didi

C++ 使用 *this 属性调用单个辅助函数

转载 作者:行者123 更新时间:2023-11-30 03:20:29 26 4
gpt4 key购买 nike

编辑:我是 C++ 的初学者,我想了解更多有关如何优化我的代码的信息。

我已经在 C++ 中创建了一个 Fraction 对象以及重载的 +、- 操作等。然而,当我谈到一元运算符时,我意识到我不知道如何以最有效的方式减少分数。所以我有一个函数 gcd 可以找到最大的除数:

int gcd (int n, int m) {

int newN = n < 0 ? -n : n;
int newM = m < 0 ? -m : m;
if (newM <= newN && newN % newM == 0) { return newM; }
else if (newN < newM) { return gcd(newM, newN); }
else { return gcd(newM, newN%newM); }
}

然后我有一个重载运算符,例如增量:

Fraction& Fraction::operator++() {
num = num + denom;

//reduce fraction
int divisor = gcd(denom,num);
num = num/divisor;
denom = denom/divisor;
if (num < 0 && denom < 0) {num *= (-1);}
if (denom < 0) {denom *= (-1);}

return *this;
}

为了提高效率,我想将代码的reduce fraction 部分放在一个单独的single 辅助函数中,因此最终函数如下所示:

Fraction& Fraction::operator++() {
num = num + denom;

//reduce fraction
reduce(num, denom);

return *this;
}

这样我就不必每次重载一元运算符时都复制和粘贴 //reduce fraction 中的任何内容。但是,我不确定 reduce(Fraction num, Fraction& denom) 函数应该是什么样子。最多我可以这样实现:

void reduce(int& num, int& denom) {
int divisor = gcd(denom,num);
num = num/divisor;
denom = denom/divisor;
if (num < 0 && denom < 0) {num *= (-1);}
if (denom < 0) {denom *= (-1);}
}

我确信上面的代码在编译过程中会遇到问题,所以我想知道是否可以向我建议任何有关有效创建 reduce fraction 函数的建议。这可能有点挑剔,因为我的原始代码运行良好,但由于我是 C++ 的新手,我想了解更多关于如何使我的代码更高效的信息。多谢!如果需要更多信息,请告诉我。

编辑:上面的代码不起作用。编译正确,但不能正确减少分数。所以 1/2 + 1/4 结果是 6/8,而不是 3/4。

最佳答案

好吧,在高层次上,您的 gcd 函数太复杂了,reduce 的最后一部分有点错误。如果只有 denom 为负,则将其反转。很好地展示了为什么将代码放入适当的函数中总是一个好主意,因为它们也可以单独测试。所以我建议为您的 reduce 和 gcd 函数编写一些单元测试。从一个简单的解决方案开始,例如

static int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}

考虑到 % semantics 并根据需要对负数进行调整.考虑一下这个函数应该已经很好了,你只需要在 reduce 中调用 std::abs(gcd(n,d))。

一般来说,您应该问问自己是否真的要为每个操作支付重规范化成本,或者是否让用户决定何时调用 reduce。

对于较低级别的优化,这里有一些提示:

  • 始终测试/测量,例如通过查看编译器使用 godbolt.org 实际生成的内容.
  • 在这种情况下,从性能的角度来看,gcd 中的递归不是问题,因为它是 tail recursive。编译器会为你把它变成一个循环。
  • reduce 中的 out 参数不利于优化,因为编译器必须证明它们不指向同一个对象。如果可能的话,在调用站点返回一个 std::pair 并使用 C++11 std::tie 或 C++17 结构化绑定(bind)会更优雅。

关于C++ 使用 *this 属性调用单个辅助函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52900393/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com