Thread: Linker Error

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    So I've been working with classes for a while. After fiddling around, I came up with two instances of code that pretty much did the same thing. I wanted one to be using a member function and the other to be non member function. It compiles fine, but it doesn't link. For the life of me I can't figure out what's wrong.

    Code:
    #include <iostream>
    using namespace std;
    
    class Fraction
    {
    public:
    
    Fraction();
    
    Fraction( const Fraction& frOld );
    Fraction( int iOld );
    Fraction( int, int );
    
    ~Fraction();
    
    int getNum();
    void setNum( int iOld );
    
    int getDenom();
    void setDenom( int iOld );
    
    void print() const;
    
    int compare( Fraction );
    
    private:
    
    int iNum;
    int iDenom;
    
    };
    
    Fraction::Fraction()
    {
    iNum = 0;
    iDenom = 1;
    }
    
    Fraction::Fraction( const Fraction& frOld )
    {
    iNum = frOld.iNum;
    iDenom = frOld.iDenom;
    }
    
    Fraction::Fraction( int iA, int iB )
    {
    iNum = iA;
    
    if ( iB )
    {
    iDenom = iB;
    }
    
    else
    {
    iDenom = 1;
    }
    
    }
    
    Fraction::Fraction( int iOld )
    {
    iNum = iOld;
    
    if ( iOld )
    {
    iDenom = iOld;
    }
    
    else
    {
    iDenom = 1;
    }
    
    }
    
    Fraction::~Fraction()
    {
    cout << "\nDestruction -- Clean out one Fraction object!" << endl;
    }
    
    int Fraction::getNum()
    {
    return iNum;
    }
    
    void Fraction::setNum( int iOld )
    {
    iNum = iOld;
    return;
    }
    
    int Fraction::getDenom()
    {
    return iDenom;
    }
    
    void Fraction::setDenom( int iOld )
    {
    if ( iOld )
    {
    iDenom = iOld;
    }
    
    else
    {
    iDenom = 1;
    }
    
    return;
    }
    
    
    void Fraction::print() const
    {
    cout << "\n\tiNum: " << iNum
    	 << "\n\tiDenom: " << iDenom << endl;
    return;
    }
    
    void printFractionArray( Fraction frAry[], int iSize )
    {
    for ( int i = 0; i < iSize; i++ )
    {
    cout << "\nFraction frAry[ " << i <<" ] : "
    << "\n\t" << frAry[ i ].getNum()
    << "\n\t" << frAry[ i ].getDenom();
    }
    
    return;
    }
    
    int compare( Fraction frA , Fraction frB )
    {
    	int iZ;
    	double dFrA;
    	double dFrB;
    	
    	double dNum1 = frA.getNum();
    	double dDenom1 = frA.getDenom();
    	double dNum2 = frB.getNum();
    	double dDenom2 = frB.getDenom();
    
    	dFrA = dNum1 / dDenom1;
    	dFrB = dNum2 / dDenom2;
    
    	if ( dFrA > dFrB )
    		iZ = 1;
    
    	else if ( dFrA < dFrB )
    		iZ = -1;
    
    	else iZ = 0;
    	
    	return iZ;
    }
    
    int main ()
    {
    	int iX;
    	int iY;
    	int iZ;
    
    	Fraction frA;
    	Fraction frB;
    	
    	cout << "CIS 25 - C++ Programming" << endl
             << "Laney College" << endl
             << "Amol Mundayoor\n" << endl
             << "Assignment Information --" << endl
             << "  Assignment Number:  Lab 7, " << endl
             << "                      Postlab Exercise #3" << endl
             << "  Written by:         Amol Mundayoor" << endl
    
    	cout << "Fraction #I --"
    					 << "\n\tEnter Numerator : ";
    				cin  >> iX;	
    				frA.setNum(iX);
    				cout << "\n\tEnter Denominator : ";
    				cin  >> iY;
    				frA.setDenom(iY);
    				cout << "Fraction #II --"
    					 << "\n\tEnter Numerator : ";
    				cin  >> iX;
    				frB.setNum(iY);
    				cout << "\n\tEnter Denominator : ";
    				cin  >> iY;
    				frB.setDenom(iY);
    				
    				cout << "Fraction I " << endl;
    				frA.print();
    				cout << "Fraction II " << endl;
    				frB.print();
    				iZ = frA.compare(frB);
    				cout << "\nThe result of comparing Fraction #1 to Fraction #2 : "
    					 << iZ << endl;
    
    				return 0;
    }
    Code:
    #include <iostream>
    using namespace std;
    
    class Fraction
    {
    public:
    
    Fraction();
    
    Fraction( const Fraction& frOld );
    Fraction( int iOld );
    Fraction( int, int );
    
    ~Fraction();
    
    int getNum();
    void setNum( int iOld );
    
    int getDenom();
    void setDenom( int iOld );
    
    void print() const;
    
    int compare( Fraction );
    
    private:
    
    int iNum;
    int iDenom;
    
    };
    
    Fraction::Fraction()
    {
    iNum = 0;
    iDenom = 1;
    }
    
    Fraction::Fraction( const Fraction& frOld )
    {
    iNum = frOld.iNum;
    iDenom = frOld.iDenom;
    }
    
    Fraction::Fraction( int iA, int iB )
    {
    iNum = iA;
    
    if ( iB )
    {
    iDenom = iB;
    }
    
    else
    {
    iDenom = 1;
    }
    
    }
    
    Fraction::Fraction( int iOld )
    {
    iNum = iOld;
    
    if ( iOld )
    {
    iDenom = iOld;
    }
    
    else
    {
    iDenom = 1;
    }
    
    }
    
    Fraction::~Fraction()
    {
    cout << "\nDestruction -- Clean out one Fraction object!" << endl;
    }
    
    int Fraction::getNum()
    {
    return iNum;
    }
    
    void Fraction::setNum( int iOld )
    {
    iNum = iOld;
    return;
    }
    
    int Fraction::getDenom()
    {
    return iDenom;
    }
    
    void Fraction::setDenom( int iOld )
    {
    if ( iOld )
    {
    iDenom = iOld;
    }
    
    else
    {
    iDenom = 1;
    }
    
    return;
    }
    
    
    void Fraction::print() const
    {
    cout << "\n\tiNum: " << iNum
    	 << "\n\tiDenom: " << iDenom << endl;
    return;
    }
    
    void printFractionArray( Fraction frAry[], int iSize )
    {
    for ( int i = 0; i < iSize; i++ )
    {
    cout << "\nFraction frAry[ " << i <<" ] : "
    << "\n\t" << frAry[ i ].getNum()
    << "\n\t" << frAry[ i ].getDenom();
    }
    
    return;
    }
    
    int Fraction::compare( Fraction frB )
    {
    	int iResult;
    	double dFrA;
    	double dFrB;
    	
    	double dNum1 = iNum;
    	double dDenom1 = iDenom;
    	double dNum2 = frB.getNum();
    	double dDenom2 = frB.getDenom();
    
    	dFrA = dNum1 / dDenom1;
    	dFrB = dNum2 / dDenom2;
    
    	if ( dFrA > dFrB )
    		iResult = 1;
    
    	else if ( dFrA < dFrB )
    		iResult = -1;
    
    	else iResult = 0;
    	
    	return iResult;
    }
    
    int main ()
    {
    	int n;
    	int iX;
    	int iY;
    	int iZ;
    	int compare(Fraction FrA, Fraction FrB);
    
    	Fraction frA;
    	Fraction frB;
    
    	cout << "CIS 25 - C++ Programming" << endl
             << "Laney College" << endl
             << "Amol Mundayoor\n" << endl
             << "Assignment Information --" << endl
             << "  Assignment Number:  Lab 7, " << endl
             << "                      Postlab Exercise #3" << endl
             << "  Written by:         Amol Mundayoor" << endl
             				cout << "Fraction #I --"
    					 << "\n\tEnter Numerator : ";
    				cin  >> iX;	
    				frA.setNum(iX);
    				cout << "\n\tEnter Denominator : ";
    				cin  >> iY;
    				frA.setDenom(iY);
    				cout << "Fraction #II --"
    					 << "\n\tEnter Numerator : ";
    				cin  >> iX;
    				frB.setNum(iX);
    				cout << "\n\tEnter Denominator : ";
    				cin  >> iY;
    				frB.setDenom(iY);
    				
    				cout << "Fraction I " << endl;
    				frA.print();
    				cout << "Fraction II " << endl;
    				frB.print();
    				iZ = compare (frA, frB);
    				cout << "\nThe result of comparing Fraction #1 to Fraction #2 : "
    					 << iZ << endl;
            
    	cout << endl;
    
    	return 0;
    }
    Any help would be greatly appreciated

    And is the "this" pointer and "->" totally different entities?

    And my professor also had told us to modify a fraction addition program so that we can add two "rectangle fractions"

    "When adding two RectangleFraction objects, the result is another RectangleFraction object that has the length to be the sum of the two (2) lengths and the width to the sum of the two (2) widths"

    I don't get what he means by that. How would I go about doing that?
    Last edited by Bash; 12-06-2007 at 05:57 PM.

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    This has nothing to do with the other question, so I've split it into a new thread. In the future, please create a new thread for unrelated questions yourself.

    So what's the error you get?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >				iZ = compare (frA, frB);
    In the second program, you never defined this compare() function. Perhaps you meant to call the member function:
    Code:
    				iZ = frA.compare (frB);

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    Sorry about that, CornedBee.

    My error:
    Code:
    Linking...
    cis25Fall2007AmolMundayoorPostlabEx1.obj : error LNK2001: unresolved external symbol "public: int __thiscall Fraction::compare(class Fraction)" (?compare@Fraction@@QAEHV1@@Z)
    Debug/cis25Fall2007AmolMundayoorPostlabEx1.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.
    
    cis25Fall2007AmolMundayoorPostlabEx1.exe - 2 error(s), 0 warning(s)
    And

    Code:
    Linking...
    cis25Fall2007AmolMundayoorPostlabEx2.obj : error LNK2001: unresolved external symbol "int __cdecl compare(class Fraction,class Fraction)" (?compare@@YAHVFraction@@0@Z)
    Debug/cis25Fall2007AmolMundayoorPostlabEx2.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.
    
    cis25Fall2007AmolMundayoorPostlabEx2.exe - 2 error(s), 0 warning(s)
    Last edited by Bash; 12-06-2007 at 06:22 PM.

  5. #5
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    See above post regarding the compare member function.

    Nice job spotting it, btw....

  6. #6
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    So where would I add "iZ = frA.compare (frB);" in the second program? I added it just before "iZ = compare (frA, frB);" and it didn't work

  7. #7
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Oh my....

    Replace it.

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Actually after perusing your code a second time, it appears you reversed the compare()'s. Look at how you defined compare() in each program, and the call to the function should match. In your first program, it's not a member function, but you are calling it as if it was.

  9. #9
    Registered User
    Join Date
    Oct 2007
    Posts
    24
    OOOOH. That worked.

    But what if I wanted to do the same thing by calling compare(); as a non-member function?

    Edit: just read what swoopy said. Be back after going over mah code.

    Edit2: I feel stupid and idiotic now. Thanks guys, you've been extremely helpful
    Last edited by Bash; 12-06-2007 at 06:48 PM.

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >And is the "this" pointer and "->" totally different entities?
    this is a pointer to the class. To access some member of the class, you could write this->some_member, for example:
    Code:
    this->iNum
    Or:
    Code:
    this->iDenom
    Or:
    Code:
    this->getNum()
    Normally you would just write this->iNum as iNum. But sometimes you have a member function which returns the class, so you'd write:
    Code:
    return *this;

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    this is a pointer that exists inside a class that points to itself. It's used by the compiler to know where the class is in memory, so it can modify member data.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    The code in the first post needs indentation in a bad way.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    No, I like it much better the way it is. It removes that pesky need for my eyes to scan left to right to find the code.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I think you're alone with that opinion
    Indentation is supposed to help you find bugs, not create them! ...Which it usually does when not indented properly, not to mention that indentation is supposed to make the code more readable and not the other way around!
    Go indentation!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  2. Crazy errors caused by class, never seen before..
    By Shamino in forum C++ Programming
    Replies: 2
    Last Post: 06-10-2007, 11:54 AM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. pointer to array of objects of struct
    By undisputed007 in forum C++ Programming
    Replies: 12
    Last Post: 03-02-2004, 04:49 AM
  5. Linking error
    By DockyD in forum C++ Programming
    Replies: 10
    Last Post: 01-20-2003, 05:27 AM