0

当我尝试使用模板编译我的程序时,我遇到了一些链接器错误:

GCD.h

#include <iostream> // allows program to perform input and output 
using namespace std; // program uses names from the std namespace 

template <class T> class GCD {
   public:
      T gcd(T x, T y);  
};

// gcd finds greatest common divisor of x and y
template <class T>
T gcd(T x, T y) {
   T greatest = 1; // current greatest common divisor, 1 is minimum

   // loop from 2 to smaller of x and y
   for ( T i = 2; i <= ( ( x < y ) ? x: y ); i++ )
   {
      // if current i divides both x and y
      if ( x % i == 0 && y % i == 0 )
     {
         greatest = i; // update greatest common divisor
     }
   } // end for

   return greatest; // return greatest common divisor found
} // end template function gcd

我收到这些链接器错误,但我不确定它们的含义:

1>Fraction.obj : error LNK2019: unresolved external symbol "public: __thiscall Fraction::Fraction(__int64,__int64)" (??0Fraction@@QAE@_J0@Z) referenced in function "public: class Fraction __thiscall Fraction::negate(void)const " (?negate@Fraction@@QBE?AV1@XZ)
1>MainProg.obj : error LNK2001: unresolved external symbol "public: __thiscall Fraction::Fraction(__int64,__int64)" (??0Fraction@@QAE@_J0@Z)
1>MainProg.obj : error LNK2019: unresolved external symbol "public: __thiscall Fraction::Fraction(void)" (??0Fraction@@QAE@XZ) referenced in function _main\

我在顶部有模板定义,所以我不确定问题是什么。

这是我的 MainProg.cpp 文件:

#include <iostream>
using std::cout;
using std::endl;

#include "Fraction.h" // include definition of class Fraction from Fraction.h
#include "GCD.h"      // include definition of gcd template function

int main()
{
    // Test constructors

    Fraction A; // create a Fraction object with default ctor
    cout << "The default object is: ";
    A.display();

    Fraction B(1,1024); // create a Fraction object with the non-default ctor
    cout << "\n\nThe non-default object is: ";
    B.display();

    Fraction C(8,-1024); // test to see if the simplify method is invoked from 
                                    //   the non-default ctor
    cout << "\n\n8/-1024 simplified is: ";
    C.display();

    // Test template gcd() function

    // implicitly invoke template function

    int intX = 1024;
    int intY = 32;

    int intAns = gcd(intX,intY); // implicit invocation
    cout << "\n\nThe greatest common divisor of 1024 and 32 is: " << intAns;

    // explicitly invoke template function

    long longX = 1024;
    long longY = 1048576;

    long longAns = gcd<long>(longX, longY); // explicit invocation
    cout << "\n\nThe greatest common divisor of 1024 and 1048576 is: " << longAns;

    // Test timesEq()
    cout << "\n\n- Test timesEq()";
    A = Fraction(2,3); //Assign new values to Fraction objects
    B = Fraction(3,5);

    // Output "before" values
    cout << "\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();

    // NOTE: Equivalent to:  C = A *= B;
    C = A.timesEq(B);

    // Output "after" values
    cout << "\n\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();
    cout << "\nC = ";
    C.display();

    // Test divideEq()
    cout << "\n\n- Test divideEq()";
    A = Fraction(2,3);  //Assign new values to Fraction objects
    B = Fraction(-7,3);

    // Output "before" values
    cout << "\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();

    // NOTE: Equivalent to:  C = A /= B;
    C = A.divideEq(B);

    // Output "after" values
    cout << "\n\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();
    cout << "\nC = ";
    C.display();

    // Test plusEq()
    cout << "\n\n- Test plusEq()";
    A = Fraction(-5,-6);  //Assign new values to Fraction objects
    B = Fraction(9,10);

    // Output "before" values
    cout << "\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();

    // NOTE: Equivalent to:  C = A += B;
    C = A.plusEq(B);

    // Output "after" values
    cout << "\n\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();
    cout << "\nC = ";
    C.display();

    // Test minusEq()
    cout << "\n\n- Test minusEq()";
    A = Fraction(2,3);  //Assign new values to Fraction objects
    B = Fraction(8,9);

    // Output "before" values
    cout << "\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();

    // NOTE: Equivalent to:  C = A -= B;
    C = A.minusEq(B);

    // Output "after" values
    cout << "\n\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();
    cout << "\nC = ";
    C.display();

    // Test negate()
    cout << "\n\n- Test negateEq()";
    A = Fraction(-2,3);  //Assign new values to Fraction objects
    B = Fraction(8,9);

    // Output "before" values
    cout << "\nA = ";
    A.display();
    cout << "\nB = ";
    B.display();

    // NOTE: Equivalent to:  C = -A;
    C = A.negate();

    // Output "after" values
    cout << "\n\nA = ";
    A.display();
    cout << "\nC = ";
    C.display();

    // Output "before" values
    cout << "\n\nB = ";
    B.display();
    cout << "\nC = ";
    C.display();

    // NOTE: Equivalent to:  C = -B;
    C = B.negate();

    // Output "after" values
    cout << "\n\nB = ";
    B.display();
    cout << "\nC = ";
    C.display();

    cout << '\n' << endl;

    return 0;

} // end main

和分数.cpp:

#include <iostream>
using namespace std;

#include "Fraction.h"
#include "GCD.h" // template function for calculating greatest common divisor

//Implementation of the timesEq() member function
//Performs similar operation as the *= operator on the built-in types
const Fraction & Fraction::timesEq(const Fraction & op )
{
    numerator *= op.numerator;
    denominator *= op.denominator;

    simplify();  // will make sure that denominator is positive and
                 //   will invoke gcd() function to reduce fraction
                 //   as much as possible

    return (*this); // returns the object which invoked the method
}

const Fraction & Fraction::plusEq (const Fraction & op )
{
    numerator *= op.denominator;
    numerator += op.numerator * denominator;
    denominator *= op.denominator;

    simplify();  // will make sure that denominator is positive and
                 //   will invoke gcd() function to reduce fraction
                 //   as much as possible

    return (*this); // returns the object which invoked the method
}

const Fraction & Fraction::minusEq (const Fraction & op )
{
    numerator *= op.denominator;
    denominator = denominator * op.denominator;
    numerator -= op.numerator;

    simplify();  // will make sure that denominator is positive and
                 //   will invoke gcd() function to reduce fraction
                 //   as much as possible

    return (*this); // returns the object which invoked the method
}

const Fraction & Fraction::divideEq (const Fraction & op )
{
    numerator *= op.denominator;
    denominator *= op.numerator;

    simplify();  // will make sure that denominator is positive and
                 //   will invoke gcd() function to reduce fraction
                 //   as much as possible

    return (*this); // returns the object which invoked the method
}

Fraction Fraction::negate(void) const
{
    return Fraction((-1 * numerator), denominator);
}

void Fraction::display(void)const {
    cout << numerator << "/" << denominator;
}

void Fraction::simplify(void)
{
    numerator /= gcd(numerator, denominator);
    denominator /= gcd(numerator, denominator);
}

分数.h:

#ifndef Fraction_incl
#define Fraction_incl

class Fraction  // Fraction class
{
public:
    Fraction (void); // default ctor
    Fraction (long long num, long long denom = 1 );  // second ctor, which
       // requires at least one long long argument

    const Fraction & plusEq (const Fraction & RHS ) ; //Adds RHS to the Fraction object invoked with this method
                                          //  (thereby modifying the Fraction object) and returns the result
    const Fraction & minusEq (const Fraction & RHS ) ; //Subtracts RHS from the Fraction object invoked with this method
                                          //  (thereby modifying the Fraction object) and returns the result
    const Fraction & timesEq (const Fraction & RHS ) ; //Multiplies RHS by the Fraction object invoked with this method
                                          //  (thereby modifying the Fraction object) and returns the result
    const Fraction & divideEq (const Fraction & RHS ) ; //Divides RHS into the Fraction object invoked with this method
                                          //  (thereby modifying the Fraction object) and returns the result

    Fraction negate (void)const; //Returns the negation of the Fraction object
                            //  invoked with the method but must NOT
                            //  modify the actual Fraction object invoked
                            //  with the method.

    long long getNum(void)const;   // Returns numerator
    long long getDenom(void)const; // Returns denominator

    void display(void)const; // Outputs to standard output stream the Fraction object
                        //   in the format: numerator/denominator

private:

    void simplify (void); // this method reduces the Fraction objects as much
                          //  as possible.  It also ensures that the denominator is
                          //  positive.
    long long numerator, // represents numerator of Fraction object
        denominator;     // represents denominator of Fraction object

};
#endif
4

1 回答 1

3

似乎您从未为这些人提供过函数定义:

public:
    Fraction (void); // default ctor
    Fraction (long long num, long long denom = 1 );

所以链接器自然找不到它们。你想要这样的东西:

Fraction::Fraction(void) : numerator(0), denominator(1) {}
Fraction::Fraction(long long num, long long denom) :
                     numerator(num), denominator(denom) {
    if ( denom == 0 ) {
        throw "denominator cannot be zero";  // Or other exception
    }
}

Fraction.cpp.

于 2013-10-24T00:03:07.020 回答