You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承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;
}
错误原因及解决方案

原因分析

链接错误本质是编译器无法找到函数的实现代码,你的情况主要是以下两点:

  1. 编译范围不全:如果编译命令只包含main.cpp和BigRealClass.cpp,未加入BigDecimalIntClass.cpp,编译器会找不到BigDecimalInt类成员函数的实现。
  2. BigReal类存在未实现的函数:头文件中声明的默认构造、BigDecimalInt参数构造、operator-、比较运算符、流重载、size()、Sign()等函数均未实现,链接时会报错找不到定义。

解决方案

  1. 完整编译所有源文件:执行编译命令时,将所有相关的.cpp文件包含进去,示例:
clang++ main.cpp BigDecimalIntClass.cpp BigRealClass.cpp -o big_real_program
  1. 补全BigReal类的所有未实现函数:
    • 默认构造函数:初始化bPoint和aPoint为0值的BigDecimalInt
    • BigDecimalInt参数构造:将整数部分设为传入值,小数部分设为0
    • operator-、比较运算符:参照BigDecimalInt的逻辑,先对齐小数位数再进行运算或比较
    • 流重载:实现<<输出整数部分+小数点+小数部分,>>解析输入字符串拆分整数和小数部分
    • size()和Sign():根据需求返回总长度或继承父类的符号判断逻辑
  2. 修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:50:37