继承BigDecimalInt实现BigReal类时遇clang链接错误exit code1求助
问题描述
已实现可处理超大整数的BigDecimalInt类,功能正常。计划开发继承自BigDecimalInt的BigReal类用于处理小数,但将BigReal引入main函数后,出现链接错误:
clang: error: linker command failed with exit code 1 (use -v to see invocation)
BigDecimalInt类头文件
#ifndef BIGDECIMALINT_BIGDECIMALINTCLASS_HPP #define BIGDECIMALINT_BIGDECIMALINTCLASS_HPP #include <iostream> #include <string> #include <deque> #include <regex> using namespace std; class BigDecimalInt{ private: string number; char sign; void setNumber(string num); bool checkValidInput(string input); public: bool operator < (const BigDecimalInt& anotherDec); bool operator > (const BigDecimalInt& anotherDec); bool operator == (const BigDecimalInt anotherDec); BigDecimalInt& operator = (BigDecimalInt anotherDec); BigDecimalInt operator + (BigDecimalInt number2); BigDecimalInt operator - (BigDecimalInt anotherDec); friend ostream &operator << (ostream &out, BigDecimalInt num); int size(); int Sign(); void push_back(char ch); void push_front(char ch); BigDecimalInt(){} BigDecimalInt(string num) { setNumber(num); } string getnum(){ return number; } }; #endif
BigDecimalInt类实现文件
#include "BigDecimalIntClass.hpp" // 检查输入合法性的正则函数 bool BigDecimalInt :: checkValidInput(string input) { regex validInput("[-+]?[0-9]+"); return regex_match(input, validInput); } // 处理字符串输入的构造辅助函数 void BigDecimalInt :: setNumber(string num) { bool validNumber = checkValidInput(num); if(validNumber) { number = num; if(number[0] == '+') { number.erase(0,1); sign = '+'; } else if (number[0] == '-') { number.erase(0,1); sign = '-'; } else { sign = '+'; } } else { cout << "Invalid" << "\n"; exit(1); } } // 重载小于运算符 bool BigDecimalInt :: operator < (const BigDecimalInt& anotherDec) { string comp1 = "", comp2 = ""; long long len1 = number.length(), len2 = anotherDec.number.length(); while (len1 < len2){ comp1 += '0'; len1++; } while (len2 < len1){ comp2 += '0'; len2++; } comp1 += number; comp2 += anotherDec.number; if(sign == '-' && anotherDec.sign == '+') { return true; } else if(sign == '+' && anotherDec.sign == '-') { return false; } else if(sign == '+' && anotherDec.sign == '+') { return comp1 < comp2; } else { return comp1 > comp2; } } // 重载大于运算符 bool BigDecimalInt :: operator > (const BigDecimalInt &anotherDec) { string comp1 = "", comp2 = ""; long long len1 = number.length(), len2 = anotherDec.number.length(); while (len1 < len2){ comp1 += '0'; len1++; } while (len2 < len1){ comp2 += '0'; len2++; } comp1 += number; comp2 += anotherDec.number; if(sign == '-' && anotherDec.sign == '+') { return false; } else if(sign == '+' && anotherDec.sign == '-') { return true; } else if(sign == '+' && anotherDec.sign == '+') { return comp1 > comp2; } else { return comp1 < comp2; } } // 重载等于运算符 bool BigDecimalInt :: operator == (const BigDecimalInt anotherDec) { if (sign == anotherDec.sign && number == anotherDec.number) { return true; } else { return false; } } // 重载赋值运算符 BigDecimalInt& BigDecimalInt :: operator = (BigDecimalInt anotherDec) { sign = anotherDec.sign; number = anotherDec.number; return *this; } // 加法实现函数 string addition(string num1,string num2) { auto it1 = num1.rbegin(); auto it2 = num2.rbegin(); string res = ""; int carry = 0; while (it1 != num1.rend()) { int twoDigitsSum; carry = 0; twoDigitsSum = ((*it1 - '0') + (*it2 - '0')); if (twoDigitsSum >= 10) { carry = 1; } res = char((twoDigitsSum % 10) + '0') + res; *(it1 + 1) = char(((*(it1 + 1) - '0') + carry) + '0'); it1++; it2++; } if (carry) { res = char((carry) + '0') + res; } return res; } // 减法实现函数 string subtraction(string num1,string num2){ deque<long long>d; string res; for (long long i = num1.length() - 1; i >= 0; i--) { if (num1[i] < num2[i]) { num1[i] = char (((num1[i] - '0') + 10) + '0'); num1[i - 1] = char (((num1[i - 1] - '0') - 1) + '0'); d.push_front((num1[i] - '0') - (num2[i] - '0')); } else { d.push_front((num1[i] - '0') - (num2[i] - '0')); } } for (auto i : d) { res += to_string(i); } return res; } // 重载加法运算符 BigDecimalInt BigDecimalInt :: operator + (BigDecimalInt number2) { BigDecimalInt result; char signNumber1 = sign, signNumber2 = number2.sign; string num1 = number, num2 = number2.number; BigDecimalInt number1 = *this; while (num1.length() < num2.length()){ num1 = '0' + num1; } while (num2.length() < num1.length()){ num2 = '0' + num2; } if (signNumber1 == signNumber2){ result.sign = signNumber1; result.number = addition(num1,num2); }else{ if(number1.sign=='-') { number1.sign = '+'; result = (number2-number1); } else{ number2.sign = '+'; result = (number1-number2); } } return result; } // 重载减法运算符 BigDecimalInt BigDecimalInt :: operator - (BigDecimalInt anotherDec) { BigDecimalInt obj; deque<long long> d; string strmin = "", res = ""; string num1 = number, num2 = anotherDec.number; char sign1 = sign, sign2 = anotherDec.sign; if (number.length() > anotherDec.number.length()) { for (long long i = 0; i < number.length() - anotherDec.number.length(); i++) { strmin += '0'; } strmin += anotherDec.number; num2 = strmin; } else if (number.length() < anotherDec.number.length()) { for (long long i = 0; i < anotherDec.number.length() - number.length(); i++) { strmin += '0'; } strmin += number; num1 = strmin; } bool ok = false, is_determined = false; if (num1 < num2) { swap(num1, num2); swap(sign1, sign2); ok = true; } if (sign1 == sign2 ) { res = subtraction(num1,num2); if(sign1=='-')ok = !ok; } else { res = addition(num1,num2); if(sign == '-') { obj.sign = '-'; is_determined = true; } else { obj.sign = '+'; is_determined = true; } } bool right = false; for (long long i = 0; i < res.length(); i++) { if (res[i] != '-' && res[i] != '0') { right = true; } if (!right && res[i] == '0') { res.erase(i, 1); i--; } } if(res.empty()) res = "0"; if (!is_determined && (ok)) { obj.sign = '-'; } else if(!is_determined) { obj.sign = '+'; } obj.number=res; return obj; } // 返回数字长度 int BigDecimalInt :: size() { int s = number.size(); return s; } // 返回符号(1表示正,0表示负) int BigDecimalInt :: Sign() { if (sign == '+') { return 1; } else { return 0; } } // 在数字末尾添加字符 void BigDecimalInt ::push_back(char ch) { number.push_back(ch); } // 在数字开头添加字符 void BigDecimalInt ::push_front(char ch) { string temp; temp = ch + number; number = temp; } // 重载输出运算符 ostream &operator<< (ostream &out, BigDecimalInt num) { if(num.sign == '+') { out << num.number ; } else { if(num.number == "0") { out << num.number ; } else { out << num.sign << num.number ; } } return out; }
BigReal类头文件
#ifndef BIGREAL_BIGREALCLASS_HPP #define BIGREAL_BIGREALCLASS_HPP #include "BigDecimalIntClass.hpp" #include <iostream> #include <string> using namespace std; class BigReal : public BigDecimalInt{ private: BigDecimalInt bPoint; // 小数点前部分 BigDecimalInt aPoint; // 小数点后部分 public: BigReal (double realNumber = 0.0); // 默认构造函数 BigReal (string realNumber); BigReal (BigDecimalInt bigInteger); BigReal (const BigReal& other); // 拷贝构造函数 BigReal (BigReal&& other); // 移动构造函数 BigReal& operator= (BigReal& other); // 赋值运算符 BigReal& operator= (BigReal&& other); // 移动赋值运算符 BigReal operator+ (BigReal& other); BigReal operator- (BigReal& other); bool operator< (BigReal anotherReal); bool operator> (BigReal anotherReal); bool operator== (BigReal anotherReal); friend ostream& operator << (ostream& out, BigReal num); friend istream& operator >> (istream& in, BigReal num); int size(); int Sign(); void set_aPoint(BigDecimalInt p){aPoint= p;} void set_bPoint(BigDecimalInt p){bPoint= p;} BigDecimalInt get_aPoint(){return aPoint;} BigDecimalInt get_bPoint(){return bPoint;} }; #endif
BigReal类实现文件
#include "BigRealClass.hpp" #include "BigDecimalIntClass.hpp" BigReal::BigReal(string realNumber){ string before,after; int z; for(int i = 0; i < realNumber.size(); i++){ if(realNumber[i] == '.') i = z; } for(int i = 0 ; i < z; i++){ before += realNumber[i]; } for(int i = z+1; i < realNumber.size(); i++){ after += realNumber[i]; } aPoint = after; bPoint = before; } BigReal::BigReal (const BigReal& other){ bPoint = other.bPoint; aPoint = other.aPoint; } BigReal::BigReal (BigReal&& other){ bPoint = move(other.bPoint); aPoint = move(other.aPoint); } BigReal& BigReal::operator= (BigReal& other){ bPoint = other.bPoint; aPoint = other.aPoint; return *this; } BigReal& BigReal::operator= (BigReal&& other){ bPoint = move(other.bPoint); aPoint = move(other.aPoint); return *this; } BigReal BigReal::operator+(BigReal& other) { BigReal result; result.aPoint = aPoint + other.aPoint; result.bPoint = bPoint + other.bPoint; return result; }
错误原因及解决方案
原因分析
链接错误本质是编译器无法找到函数的实现代码,你的情况主要是以下两点:
- 编译范围不全:如果编译命令只包含
main.cpp和BigRealClass.cpp,未加入BigDecimalIntClass.cpp,编译器会找不到BigDecimalInt类成员函数的实现。 - BigReal类存在未实现的函数:头文件中声明的默认构造、BigDecimalInt参数构造、
operator-、比较运算符、流重载、size()、Sign()等函数均未实现,链接时会报错找不到定义。
解决方案
- 完整编译所有源文件:执行编译命令时,将所有相关的.cpp文件包含进去,示例:
clang++ main.cpp BigDecimalIntClass.cpp BigRealClass.cpp -o big_real_program
- 补全BigReal类的所有未实现函数:
- 默认构造函数:初始化
bPoint和aPoint为0值的BigDecimalInt - BigDecimalInt参数构造:将整数部分设为传入值,小数部分设为0
operator-、比较运算符:参照BigDecimalInt的逻辑,先对齐小数位数再进行运算或比较- 流重载:实现
<<输出整数部分+小数点+小数部分,>>解析输入字符串拆分整数和小数部分 size()和Sign():根据需求返回总长度或继承父类的符号判断逻辑
- 默认构造函数:初始化
- 修复BigReal的string构造函数逻辑:修正未初始化
z的问题,正确拆分整数和小数部分:
BigReal::BigReal(string realNumber){ string before, after; size_t z = realNumber.find('.'); if(z == string::npos){ before = realNumber; after = "0"; } else { before = realNumber.substr(0, z); after = realNumber.substr(z+1); } // 处理空输入情况,比如".123"或"123." if(before.empty()) before = "0"; if(after.empty()) after = "0"; bPoint = before; aPoint = after; }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

