* Separate compilation * Encapsulation - separate the specification of how you use the the class from the details of how the class is implemented. * Separate interface from implementation. * Do this in C++ by having separate files for interface and implementation. * Currently we have been putting our entire programs in one file. * It is conducive to reuse and enscapsulation to put each class in its own file. * Then you can use the same class in a different program by using the same file, rather than copying and pasting. * You get a single point of control. * Interface goes in a header file: *.h * Implementation goes in the cpp file: *.cpp For example: time.h -------------- #include class Time { public: Time(); Time(int theHours, int theMinutes, int theSeconds); int getHours() const { return hours; } int getMinutes() const { return minutes; } int getSeconds() const { return seconds; } void setHours(int newHours) { hours = newHours; } void setMinutes(int newMinutes) { minutes = newMinutes; } void setSeconds(int newSeconds) { seconds = newSeconds; } void tick(); friend ostream& operator <<(ostream& os, const Time& t); friend istream& operator >>(istream& is, Time& t); private: int hours; int minutes; int seconds; }; time.cpp ------------- #include "time.h" #include #include #include Time::Time() : hours(0), minutes(0), seconds(0) {} Time::Time(int theHours, int theMinutes, int theSeconds) : hours(theHours), minutes(theMinutes), seconds(theSeconds) { if(hours > 23 || minutes > 59 || seconds > 59 || hours < 0 || minutes < 0 || seconds < 0) { cout << "Invalid time given.\n"; exit(1); } } void Time::tick() { if(seconds == 59) { if(minutes == 59) { if(hours == 23) { hours = 0; } else { hours++; } minutes = 0; seconds = 0; } else { minutes++; seconds = 0; } } else { seconds++; } } ostream& operator <<(ostream& os, const Time& t) { os << t.hours << ":" << t.minutes << ":" << t.seconds; return os; } // Must be in form hh:mm:ss istream& operator >>(istream& is, Time& t) { string s; is >> s; if(s.length() != 8) { cout << "Not in proper form.\n"; exit(1); } t.hours = (s[0] -'0') * 10 + s[1] - '0'; t.minutes = (s[3] - '0') * 10 + s[4] - '0'; t.seconds = (s[6] - '0') * 10 + s[7] - '0'; if(t.hours > 23 || t.minutes > 59 || t.seconds > 59 || t.hours < 0 || t.minutes < 0 || t.seconds < 0) { cout << "Invalid time given.\n"; exit(1); } return is; } main.cpp ----------------- #include "time.h" #include int main() { Time t; cout << t << endl; cout << "Enter a time of the form hh:mm:ss "; cin >> t; cout << "You entered " << t << endl; t.tick(); cout << "One second later: " << t << endl; return 0; } * Compile like: g++ -o timer main.cpp time.cpp OR g++ -c main.cpp g++ -c time.cpp g++ -o timer main.o time.o Why the latter? If you only changed one of the cpp files, you only need to compile that one. Might save time on large programs. * Watch out for including a file twice: foo.h -------- #include "bar.h" ... blah.h -------- #include "foo.h" #include "bar.h" ... This will give you a bunch of errors saying that things are defined multiple times. You can make sure a header file only gets included once by putting "include guards" in the file. #ifndef FOO_H #define FOO_H ... #endif