Linking problems, class problems

This is a discussion on Linking problems, class problems within the C++ Programming forums, part of the General Programming Boards category; I thought I had a pretty good handle on this class thing, but once again, the compiler has humbled me. ...

  1. #1
    Kill Clear Channel Kheila's Avatar
    Join Date
    Oct 2005
    Location
    St. Paul, MN
    Posts
    23

    Linking problems, class problems

    I thought I had a pretty good handle on this class thing, but once again, the compiler has humbled me.

    Here's what I have. There are 3 files. I made sure they're all included in the same project before compiling.
    Code:
    /***************************************
    CTime.h
    by Meghan
    11/17/05
    Lab 10
    Contains the definition of the class
    CTime.
    ****************************************/
    
    class CTime
    {
    	public:
    		CTime();                  //default constructor
    		CTime(int, int, int);     //constructor
    		~CTime();                 //destructor
    		
    		void getHours(int&) const;            //function prototypes
    		void getMinutes(int&) const;
    		void getSeconds(int&) const;
    		void setHours(int);
    		void setMinutes(int);
    		void setSeconds(int);
    		CTime add(CTime);
    		
    	private:
    		int hours;
    		int minutes;
    		int seconds;
    		
    
    };
    
    CTime::CTime()           //default constructor
    {
           hours = 0;
           minutes = 0;
           seconds = 0;
    }
    inline CTime::CTime(int hr, int min, int sec)            //constructor
    {
    	hr = 0;
    	min = 0;
    	sec = 0;
    }
    
    
    inline void CTime::getHours(int& hr) const
    {
    	hr = hours;
    }
    
    inline void CTime::getMinutes(int& min) const
    {
    	min = minutes;
    }
    
    inline void CTime::getSeconds(int& sec) const
    {
    	sec = seconds;
    }
    
    inline void CTime::setHours(int hr)
    {
    	if (hr<=60)
    		hr = hours;
    	else
    		hr = 0;
    }
    
    inline void CTime::setMinutes(int min)
    {
    	if (min<=60)
    		min = minutes;
    	else 
    		min = 0;
    }
    
    inline void CTime::setSeconds(int sec)
    {
    	if (sec<=60)
    		sec = seconds;
    	else
    		sec = 0;
    }
    Code:
    /***************************************
    CTime.cpp
    by Meghan
    11/17/05
    Lab 10
    Contains the CTime member function that
    adds the two times together.
    ****************************************/
    
    #include <cstdlib>
    #include <iostream>
    #include "CTime.h"
    
    using namespace std;
    	
    CTime CTime::add(CTime t2)
    {
    	long t1Seconds;
    	long t2Seconds;
    	long t3Seconds;
    	CTime temp;
    
    	//converts time1 from hours:minutes:seconds to seconds
    	t1Seconds = (long)hours*3600 + (long)minutes*60 + (long)seconds;
    	
    	//converts time2 from hours:minutes:seconds to seconds
    	t2Seconds = (long)t2.hours*3600 + (long)t2.minutes*60 + (long)t2.seconds;
    	
    	//adds time1 and time2
    	t3Seconds = t1Seconds + t2Seconds;
    	
    	temp.hours = t3Seconds/60;
    	temp.minutes = (t3Seconds%60)/60;
    	temp.seconds = (t3Seconds%60)%60;
    
    	return temp;
    }
    Code:
    /***************************************
    TimeApp.cpp
    by Meghan
    11/17/05
    Lab 10
    A program that gets two time values
    from the user, adds them, and displays
    the result.
    ****************************************/
    
    #include <cstdlib>
    #include <iostream>
    #include "CTime.h"
    
    using namespace std;
    
    int main()
    {	
    	CTime time1;           //first time value from user input
    	CTime time2;           //second time value from user input
    	CTime sumTime;         //sum of times the user entered
    	char ch;               //holds the colon character
    	int hrs1;              //hours value of time1
    	int min1;              //minutes value of time1
    	int sec1;              //seconds value of time1
    	int hrs2;              //hours value of time2
    	int min2;              //minutes value of time2
    	int sec2;              //seconds value of time2
    	int sumHrs;            //hours value of sum
    	int sumMin;            //minutes value of sum
    	int sumSec;            //seconds value of sum
    	
    	
    	cout << "Enter a time in 00:00:00 format:" << endl;
    	cin >> hrs1;
    	cin.get(ch);                 //gets the colon character
    	cin >> min1;
    	cin.get(ch);
    	cin >> sec1;
    	
    	time1.setHours(hrs1);         //stores user input in hours value
    	time1.setMinutes(min1);       //stores user input in minutes value
    	time1.setSeconds(sec1);       //stores user input in seconds value
    	
    	cout << "Enter another time in the same format:" << endl;
    	cin >> hrs2;
    	cin.get(ch);                //gets the colon character
    	cin >> min2;
    	cin.get(ch);
    	cin >> sec2;
    	
    	time2.setHours(hrs2);        //stores user input in hours value
    	time2.setMinutes(min2);      //stores user input in minutes value
    	time2.setSeconds(sec2);      //stores user input in seconds value
    	
    	sumTime = time1.add(time2);             //adds the two times together
    	sumTime.getHours(sumHrs);
    	sumTime.getMinutes(sumMin);
    	sumTime.getSeconds(sumSec);
    	
    	cout << "The sum of " << hrs1 << ":" << min1 << ":";
    	cout << sec1 << " and " << hrs2 << ":" << min2;
    	cout << ":" << sec2 << " is " << sumHrs << ":";
    	cout << sumMin << ":" << sumSec << endl;
    	
    	return 0;
    }
    The compiler says (several times apiece):
    "multiple definition of `CTime::CTime()' "
    " first defined here "
    "[Linker error] undefined reference to `CTime::~CTime()' "

    See anything I'm doing wrong? Any ideas are appreciated. Thanks.
    to Absent Toast

  2. #2
    ^ Read Backwards^
    Join Date
    Sep 2005
    Location
    Earth
    Posts
    282

  3. #3
    Kill Clear Channel Kheila's Avatar
    Join Date
    Oct 2005
    Location
    St. Paul, MN
    Posts
    23
    Hmm. That's good to know (wish that had been covered in class). It's kind of unclear exactly where to place this, here's what I did, and I know it's wrong because the compiler still doesn't like it:
    Code:
    /***************************************
    CTime.h
    by Meghan
    11/17/05
    Lab 10
    Contains the definition of the class
    CTime.
    ****************************************/
    #ifndef CTIME_H
    #define CTIME_H
    #endif
    
    class CTime
    {
    	public:
    		CTime();                  //default constructor
    		CTime(int, int, int);     //constructor
    		~CTime();                 //destructor
    		
    		void getHours(int&) const;            //function prototypes
    		void getMinutes(int&) const;
    		void getSeconds(int&) const;
    		void setHours(int);
    		void setMinutes(int);
    		void setSeconds(int);
    		CTime add(CTime);
    		
    	private:
    		int hours;
    		int minutes;
    		int seconds;
    		
    
    };
    
    CTime::CTime()           //default constructor
    {
           hours = 0;
           minutes = 0;
           seconds = 0;
    }
    inline CTime::CTime(int hr, int min, int sec)            //constructor
    {
    	hr = 0;
    	min = 0;
    	sec = 0;
    }
    
    
    inline void CTime::getHours(int& hr) const
    {
    	hr = hours;
    }
    
    inline void CTime::getMinutes(int& min) const
    {
    	min = minutes;
    }
    
    inline void CTime::getSeconds(int& sec) const
    {
    	sec = seconds;
    }
    
    inline void CTime::setHours(int hr)
    {
    	if (hr<=60)
    		hr = hours;
    	else
    		hr = 0;
    }
    
    inline void CTime::setMinutes(int min)
    {
    	if (min<=60)
    		min = minutes;
    	else 
    		min = 0;
    }
    
    inline void CTime::setSeconds(int sec)
    {
    	if (sec<=60)
    		sec = seconds;
    	else
    		sec = 0;
    }
    I also tried sticking it in the .cpp files, that didn't work either.
    Last edited by Kheila; 11-21-2005 at 11:02 PM.
    to Absent Toast

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Code:
    #ifndef CTIME_H
    #define CTIME_H
    
    //Your header file code here
    
    
    #endif
    It works like a regular if statement: when the if condition is true then everything between #ifand #endif is included. If the condition is false, then the whole block delimited by #if and #endif is skipped. The first time that code is included CTIME_H won't be defined, so the compiler will enter the if-endif block. The first line defines CTIME_H(which just means it exists) and then the rest of the code is included(an include statement is a direction to replace the include statement with the contents of the specified file). The next time you try to include that file, #ifndef CTIME_H evaluates to false, so the block is skipped and none of the code is included.
    Last edited by 7stud; 11-21-2005 at 11:04 PM.

  5. #5
    Kill Clear Channel Kheila's Avatar
    Join Date
    Oct 2005
    Location
    St. Paul, MN
    Posts
    23
    Ah, got it. It seems to be working now. There's another problem, though: in the CTime.cpp file, I need the function add() to return a value of the type CTime. Is this possible? If so, what do I need to change in that bit of code to get it to return a value of the type CTime? Right now the compiler says I don't name a type.
    to Absent Toast

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    It looks like it does:
    Code:
    CTime CTime::add(CTime t2)
    {
    	long t1Seconds;
    	long t2Seconds;
    	long t3Seconds;
    	CTime temp;
    
    	//converts time1 from hours:minutes:seconds to seconds
    	t1Seconds = (long)hours*3600 + (long)minutes*60 + (long)seconds;
    	
    	//converts time2 from hours:minutes:seconds to seconds
    	t2Seconds = (long)t2.hours*3600 + (long)t2.minutes*60 + (long)t2.seconds;
    	
    	//adds time1 and time2
    	t3Seconds = t1Seconds + t2Seconds;
    	
    	temp.hours = t3Seconds/60;
    	temp.minutes = (t3Seconds%60)/60;
    	temp.seconds = (t3Seconds%60)%60;
    
    	return temp;
    }

  7. #7
    Kill Clear Channel Kheila's Avatar
    Join Date
    Oct 2005
    Location
    St. Paul, MN
    Posts
    23
    I thought so too, but the compiler says "`CTime' does not name a type ".
    to Absent Toast

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Are you still including CTime.h in your .cpp file?

    Code:
    #include <cstdlib>
    #include <iostream>
    #include "CTime.h"
    
    using namespace std;
    	
    CTime CTime::add(CTime t2)

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Post the error and mark the line number with a comment in your code.

  10. #10
    Kill Clear Channel Kheila's Avatar
    Join Date
    Oct 2005
    Location
    St. Paul, MN
    Posts
    23
    Yes, but I put the #ifndef etc. statements in the CTime.cpp file as well as in the header file, because otherwise it still includes the header file multiple times. This seems like it might be why it doesn't recognize the CTime data type. So...either way it doesn't work. This is the exact wording of the compiler error: "CTime.cpp:18: error: `CTime' does not name a type"

    Here's the code, I marked where the error occurred:
    Code:
    /***************************************
    CTime.cpp
    by Meghan
    11/17/05
    Lab 10
    Contains the CTime member function that
    adds the two times together.
    ****************************************/
    #include <cstdlib>
    #include <iostream>
    #ifndef CTIME_H
    #define CTIME_H
    #include "CTime.h"
    
    
    using namespace std;
    
    /
    CTime CTime::add(CTime t2)             //this line contains the error
    {
    	long t1Seconds;
    	long t2Seconds;
    	long t3Seconds;
    	CTime temp;
    
    	//converts time1 from hours:minutes:seconds to seconds
    	t1Seconds = (long)hours*3600 + (long)minutes*60 + (long)seconds;
    	
    	//converts time2 from hours:minutes:seconds to seconds
    	t2Seconds = (long)t2.hours*3600 + (long)t2.minutes*60 + (long)t2.seconds;
    	
    	//adds time1 and time2
    	t3Seconds = t1Seconds + t2Seconds;
    	
    	temp.hours = t3Seconds/60;
    	temp.minutes = (t3Seconds%60)/60;
    	temp.seconds = (t3Seconds%60)%60;
    
    	return temp;
    }
    #endif
    to Absent Toast

  11. #11
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Yes, but I put the #ifndef etc. statements in the CTime.cpp file
    No, no, no. Inclusion guards are only used for header files. You only include header files so there is no possible duplication for your .cpp files. As long as your class declaration is included in main(), the magic of the compiling/linking process will make the connection between the funtion calls you make in main(), to their declarations that are included at the top of the file to their definitions in a separate .cpp file.

    because otherwise it still includes the header file multiple times.
    You can #include your header file 15 times in every file, but it will still only be included once if you have the inclusion guards around it. I explained before: the first time the compiler includes the header file in a file, the condition:

    #ifndef CTIME_H

    will be false. Therefore the compiler enters the if-endif block and includes everything. But, as it does that the compiler encounters the line that says:

    #define CTIME_H

    That means that something called CTIME_H now exists. The next time the compiler encounters #include "CTime.h" it looks at the header file again, but this time the statement:

    #ifndef CTIME_H

    evaluates to false, so the whole if-endif block is skipped, so the compiler includes a blank file. That means the declarations won't be included more than once, and you won't get any compiler errors saying you are redeclaring the same variables.
    Last edited by 7stud; 11-22-2005 at 12:00 AM.

  12. #12
    Kill Clear Channel Kheila's Avatar
    Join Date
    Oct 2005
    Location
    St. Paul, MN
    Posts
    23
    Ok, I took them out, but now I'm still getting errors saying "multiple definition of `CTime::CTime()' " like I got before I put them in the header file. What you explained makes sense, which is why I don't understand why I'm still getting the same errors.

    Argh.

    I'm going to continue working on this tomorrow morning. Thanks for all your help!
    Last edited by Kheila; 11-22-2005 at 12:09 AM.
    to Absent Toast

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,662
    Ok.

    The problem is that you have the inline function definitions in the same header file as your class declaration, so when you include the header file in CTime.cpp in order to get the class declaration in there, you end up getting the inline function definitions in there(remember an include statement is replaced with the contents of the file). You also have to include your class declaration in the file containing main(), so you end up getting the inline function definitions in main() as well. The result is you have functions with the same name defined in two different files, and that is not allowed, so that is producing the error you are seeing. You're allowed to include the declaration for your class in more than one file, but you're only allowed to have the definition of a function in a single file.

    So, try putting your inline functions in a separate header file and only include that header file in one file: main(). The inclusion guards won't help in that header file because they won't prevent you from including a header file in multiple files, they only prevent you from including a header file multiple times in the same file.
    Last edited by 7stud; 11-22-2005 at 01:05 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Linking error with static template class members
    By cunnus88 in forum C++ Programming
    Replies: 6
    Last Post: 04-02-2009, 12:31 PM
  3. Derived class linking error
    By Enahs in forum C++ Programming
    Replies: 3
    Last Post: 11-12-2005, 09:18 PM
  4. base class pointer problems
    By ... in forum C++ Programming
    Replies: 3
    Last Post: 11-16-2003, 10:27 PM
  5. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 06:18 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21