C++;使用*此属性调用单个帮助器函数 编辑:我是C++初学者,我想了解更多关于优化我的代码的内容。 我在C++中创建了一个分数对象以及重载+,-操作等。但是当我来到一元运算符时,我意识到我不知道如何以最有效的方式减少分数。我有一个函数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); } }
这样我就不必每次重载一元运算符时都复制和粘贴C++;使用*此属性调用单个帮助器函数 编辑:我是C++初学者,我想了解更多关于优化我的代码的内容。 我在C++中创建了一个分数对象以及重载+,-操作等。但是当我来到一元运算符时,我意识到我不知道如何以最有效的方式减少分数。我有一个函数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); } },c++,performance,operator-overloading,this,fractions,C++,Performance,Operator Overloading,This,Fractions,这样我就不必每次重载一元运算符时都复制和粘贴//reduce fraction中的任何内容。但是,我不确定reduce(分数num、分数&denom)函数应该是什么样子。我最多可以这样实现它: Fraction& Fraction::operator++() { num = num + denom; //reduce fraction reduce(num, denom); return *this; } void reduce(int& num, int& den
//reduce fraction
中的任何内容。但是,我不确定reduce(分数num、分数&denom)函数应该是什么样子。我最多可以这样实现它:
Fraction& Fraction::operator++() {
num = num + denom;
//reduce fraction
reduce(num, denom);
return *this;
}
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);}
}
void reduce(int&num,int&denom){
整数除数=gcd(denom,num);
num=num/除数;
denom=denom/除数;
如果(num<0&&denom<0){num*=(-1);}
如果(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);
}
如果需要负数,请进行调整。考虑一下,函数应该已经很好了,您只需要在reduce中调用std::abs(gcd(n,d))
一般来说,你应该问问自己,你是真的想在每次操作中支付重整化成本,还是让用户决定何时调用reduce
对于较低级别的优化,以下是一些提示:
- 始终进行测试/测量,例如通过查看编译器实际生成的内容
- 从性能的角度来看,gcd中的递归在本例中不是一个问题,因为它是,编译器将为您将其转换为一个循环
- reduce中的out参数不利于优化,因为编译器必须证明它们不指向同一对象。如果可能的话,返回一个std::pair并在调用站点上使用C++11 std::tie或C++17结构化绑定更为优雅
static int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}