C++友元函数实现问题:Num_Fact对象参数的GCD/LCM函数栈溢出
解决Num_Fact类友元GCD/LCM函数的栈溢出问题
问题根源
你当前的友元GCD函数实现会触发无限递归:
Num_Fact GCD(Num_Fact A, Num_Fact B) { return GCD(A.getnum(), B.getnum()); }
当调用GCD(A.getnum(), B.getnum())时,不存在接收两个int参数的GCD函数匹配,编译器会将int隐式转换为Num_Fact(通过类的构造函数),最终又调用回这个接收Num_Fact的友元GCD函数,无限循环直接导致栈溢出。
解决方案
1. 实现整数版GCD辅助函数
先编写处理原始整数的GCD核心逻辑,用迭代版避免递归风险:
int gcd_int(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; }
2. 修正友元GCD函数实现
调用整数版GCD,用计算结果构造Num_Fact对象返回:
Num_Fact GCD(Num_Fact A, Num_Fact B) { int result = gcd_int(A.getnum(), B.getnum()); return Num_Fact(result); // 依赖Num_Fact的int类型构造函数 }
3. 实现LCM函数
利用GCD结果计算最小公倍数,同样先实现整数版辅助函数:
int lcm_int(int a, int b) { return (a / gcd_int(a, b)) * b; // 先除后乘降低溢出概率 } Num_Fact LCM(Num_Fact A, Num_Fact B) { int result = lcm_int(A.getnum(), B.getnum()); return Num_Fact(result); }
完整示例代码
包含Num_Fact类的基础结构与测试逻辑:
#include <iostream> #include <string> using namespace std; class Num_Fact { private: int num; public: // 接收int的构造函数 Num_Fact(int n) : num(n) {} // 获取内部数值的成员函数 int getnum() const { return num; } // 示例输出函数(可替换为质因数分解逻辑) string output() const { return to_string(num); } // 友元函数声明 friend Num_Fact GCD(Num_Fact, Num_Fact); friend Num_Fact LCM(Num_Fact, Num_Fact); }; // 整数版GCD辅助函数 int gcd_int(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } // 整数版LCM辅助函数 int lcm_int(int a, int b) { return (a / gcd_int(a, b)) * b; } // 友元GCD函数实现 Num_Fact GCD(Num_Fact A, Num_Fact B) { int gcd_val = gcd_int(A.getnum(), B.getnum()); return Num_Fact(gcd_val); } // 友元LCM函数实现 Num_Fact LCM(Num_Fact A, Num_Fact B) { int lcm_val = lcm_int(A.getnum(), B.getnum()); return Num_Fact(lcm_val); } // 测试代码 int main() { int value; cout << "Key in number A: "; cin >> value; Num_Fact A(value); cout << "Key in number B: "; cin >> value; Num_Fact B(value); cout << " A = "<< A.output() <<" = "<<A.getnum()<<endl; cout << " B = " <<B.output() << " = " << B.getnum() << endl; Num_Fact C = GCD(A, B); cout << " GCD(A,B) = " << C.output() << " = " << C.getnum() << endl; Num_Fact D = LCM(A, B); cout << " LCM(A,B) = " << D.output() << " = " << D.getnum() << endl; return 0; }
关键注意点
- 确保
Num_Fact类存在接收int的构造函数,否则无法用计算结果构造返回对象。 - 必须依赖独立的整数版计算逻辑,避免友元函数递归调用自身。
- 若处理大数值,可将辅助函数的参数和返回值改为
long long类型,进一步避免整数溢出。
内容的提问来源于stack exchange,提问作者Drick
相关产品推荐
相关产品推荐

