当我尝试使用模板编译我的程序时,我遇到了一些链接器错误:
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