c++ 我很难修复这个错误,我还是个新手,

nwsw7zdq  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(98)

Main.cpp

#include <iostream>
#include "rationalsCN.h"

using namespace std;
using namespace Carson;

int main() {
    Rational r1(3, 5);
    Rational r2(7);

    Rational r3;
    cout << "Enter a rational number in the format numerator/denominator: ";
    cin >> r3;

    cout << "r1 = " << r1 << endl;
    cout << "r2 = " << r2 << endl;
    cout << "r3 = " << r3 << endl;
 
    cout << "r1 == r2: " << (r1 == r2) << endl;
    cout << "r1 != r2: " << (r1 != r2) << endl;
    cout << "r1 < r2: " << (r1 < r2) << endl;
    cout << "r1 <= r2: " << (r1 <= r2) << endl;
    cout << "r1 > r2: " << (r1 > r2) << endl;
    cout << "r1 >= r2: " << (r1 >= r2) << endl;

    Rational sum = r1 + r2;
    Rational diff = r1 - r2;
    Rational prod = r1 * r2;
    Rational quotient = r1 / r2;

    cout << "r1 + r2 = " << sum << endl;
    cout << "r1 - r2 = " << diff << endl;
    cout << "r1 * r2 = " << prod << endl;
    cout << "r1 / r2 = " << quotient << endl;

    Rational zero;
    Rational divByZero(3, 0);
    Rational zeroByZero(0, 0);
    Rational zeroInNum(0, 3);
    Rational negNum(-3, 8);
    Rational negDenom(3, -8);
    Rational negBoth(-3, -8);

    cout << "zero = " << zero << endl;
    cout << "divByZero = " << divByZero << endl;
    cout << "zeroByZero = " << zeroByZero << endl;
    cout << "zeroInNum = " << zeroInNum << endl;
    cout << "negNum = " << negNum << endl;
    cout << "negDenom = " << negDenom << endl;
    cout << "negBoth = " << negBoth << endl;

    return 0;
}

字符串

  • 中国.h**
#include <iostream>

namespace Carson {
    class Rational {
        int num, denom;
        int gcd(int a, int b);
        void reduce();
        void initialize(int n, int d);
    public:
        Rational();
        Rational(int n);
        Rational(int n, int d);
        friend std::istream& operator>>(std::istream& is, Rational& r);
        friend std::ostream& operator<<(std::ostream& os, const Rational& r);
        friend bool operator==(const Rational& r1, const Rational& r2);
        friend bool operator<(const Rational& r1, const Rational& r2);
        friend bool operator<=(const Rational& r1, const Rational& r2);
        friend bool operator>(const Rational& r1, const Rational& r2);
        friend bool operator>=(const Rational& r1, const Rational& r2);
        friend bool operator!=(const Rational& r1, const Rational& r2);
        friend Rational operator+(const Rational& r1, const Rational& r2);
        friend Rational operator-(const Rational& r1, const Rational& r2);
        friend Rational operator*(const Rational& r1, const Rational& r2);
        friend Rational operator/(const Rational& r1, const Rational& r2);
        friend Rational operator-(const Rational& r);
    };
}

#endif


[*]中国.cpp**

#include "rationalsCN.h"

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

namespace Carson {
    Rational::Rational(int numerator, int denominator) {
        if (denominator == 0) {
            throw std::invalid_argument("Denominator can't be zero");
        }
        int divisor = gcd(numerator, denominator);
        num = numerator / divisor;
        denom = denominator / divisor;

        if (denom < 0) {
            num *= -1;
            denom *= -1;
        }
    }

    Rational::Rational(int numerator) : Rational(numerator, 1) {}
    
    Rational::Rational() : Rational(0, 1) {}

    std::ostream& operator<<(std::ostream& os, const Rational& r) {
        os << r.num << "/" << r.denom;
        return os;
    }

    std::istream& operator>>(std::istream& is, Rational& r) {
        int numerator, denominator;
        char slash;

        is >> numerator >> slash >> denominator;

        if (!is || slash != '/') {
            is.setstate(std::ios_base::failbit);
            return is;
        }

        r = Rational(numerator, denominator);
        return is;
    }

    bool operator==(const Rational& r1, const Rational& r2) {
        return r1.num == r2.num && r1.denom == r2.denom;
    }

    bool operator<(const Rational& r1, const Rational& r2) {
        return r1.num * r2.denom < r2.num * r1.denom;
    }

    bool operator<=(const Rational& r1, const Rational& r2) {
        return r1.num * r2.denom <= r2.num * r1.denom;
    }

    bool operator>(const Rational& r1, const Rational& r2) {
        return r1.num * r2.denom > r2.num * r1.denom;
    }

    bool operator>=(const Rational& r1, const Rational& r2) {
        return r1.num * r2.denom >= r2.num * r1.denom;
    }

    bool operator!=(const Rational& r1, const Rational& r2) {
        return !(r1 == r2);
    }

    Rational operator+(const Rational& r1, const Rational& r2) {
        int lcm = (r1.denom * r2.denom) / gcd(r1.denom, r2.denom);
        int num = (lcm / r1.denom) * r1.num + (lcm / r2.denom) * r2.num;
        return Rational(num, lcm);
    }

    Rational operator-(const Rational& r1, const Rational& r2) {
        return r1 + Rational(-r2.num, r2.denom);
    }

    Rational operator*(const Rational& r1, const Rational& r2) {
        return Rational(r1.num * r2.num, r1.denom * r2.denom);
    }

    Rational operator/(const Rational& r1, const Rational& r2) {
        if (r2.num == 0) {
            throw std::invalid_argument("division by zero");
        }

        return Rational(r1.num * r2.denom, r1.denom * r2.num);
    }

    Rational operator-(const Rational& r) {
        return Rational(-r.num, r.denom);
    }
}


我得到这些错误

/usr/bin/ld: /tmp/cczoz2hS.o: in function Carson::Rational::Rational(int, int)':
rationalsCN.cpp:(.text+0x9c): undefined reference to Carson::Rational::gcd(int, int)'
collect2: error: ld returned 1 exit status


我以前从来没有遇到过这个错误,而且它没有说明它在哪一行。我知道它在rationalsCN.cpp中,但我不确定要修改什么。而且我相信可能有更有效的方法来完成我所做的事情。

khbbv19g

khbbv19g1#

四个变化
我做了四处改动来编译你的程序。
1.将include guard添加到文件RationsCN.h中。您的代码可能已经有了这个,但它没有在SO中发布。
1.使gcd成为类Rational的静态函数。目前,它是一个成员函数。您可能希望删除此函数,以支持std::gcd
1.将函数gcd的定义范围限定为RationsCN.cpp文件中的Rational类。
1.将对函数gcd的引用的作用域设置为函数operator+中的类Rational
现在它可以运行了,但是当您在构造函数Rational(int numerator, int denominator)中调用gcd时,会抛出异常。

使用静态函数

class Rational {
        int num, denom;
        static int gcd(int a, int b);  // MAKE `gcd` A STATIC FUNCTION
        void reduce();
        void initialize(int n, int d);
    public:
    // ...

字符串

作用域函数gcd的定义

namespace Carson {
    int Rational::gcd(int a, int b) {   // ADD SCOPE RESOLUTION
        return b == 0 ? a : gcd(b, a % b);
    }
}

友元函数中对函数gcd的作用域引用

Rational operator+(const Rational& r1, const Rational& r2) {
        int lcm = (r1.denom * r2.denom) / Rational::gcd(r1.denom, r2.denom);
        int num = (lcm / r1.denom) * r1.num + (lcm / r2.denom) * r2.num;
        return Rational(num, lcm);
    }


建议
写作课Rational对C++学生来说是一个很好的练习。很高兴看到你接受挑战。
下面是一些提示。
1.使用类型long long int,而不是int。这会给你更多的空间,在一系列的计算导致分母爆炸之前。我在一个矩阵求逆程序中使用Rational作为元素类型时看到了这一点!
1.请参见Comparing Rational Numbers Without Overflow
1.请参阅Boost implementation of operator+=,了解一些延迟溢出的优化技巧。
1.根据其Map的复合指派运算子,实作二元运算子,例如+-*/。例如:

// Defined within class `Rational`, as a "hidden friend."
friend constexpr Rational operator+ (Rational lop, Rational const& rop)
{ 
    return lop += rop;
}


玩得开心点!

oyt4ldly

oyt4ldly2#

在MySQL. h中,gcd是命名空间Carson中类Rational的方法。
gcd是命名空间Carson中的一个函数。
就像Richard和JaMiT评论的那样,头文件可以编译,但没有Rational::gcd的实现。
最小的改动是从MySQL. h中删除gcd的声明。只有cpp文件能够访问它。您也可以将其设置为静态的。
如果你需要gcd可以被其他类访问,你可以:

  • 更新BSCN.h以使gcd成为静态的。更新BSCN.cpp以实现Rational::gcd而不仅仅是gcd
  • 仅更新SCN. h,使gcd成为Rational类之外但在Carson命名空间内的函数。

相关问题