Classes
=======
In C++ a class splits into two sepatrate parts:
- interface, placed in a header file: x.h
- implementation, placed in a source: x.cpp
and compiled separatedly to: x.o (x.a or x.so)
Users of the class includes the header file (x.h), and should
link the object file (x.o).
____________________
| ------- |
| | x.h | |
| ------- |
| / \ |
| / ___ \|
| / | \
| --------- | ------------
| | x.cpp | | | main.cpp |
| --------- | ------------
| | | |
| | | |
| | | |
| --------- | ------------
| | x.o | | | main.o |
| --------- | ------------
|________ \____| /
\ /
\ /
---------
| a.out |
---------
A good idea to imagine, how we would like to use our class.
An example: class date, store, retrive and compare date values.
#include <iostream>
#include "date.h"
int main()
{
date d(1);
while ( std::cin >> d )
{
d += 40;
std::cout << d << std::endl;
}
std::cin.clear();
date d2( 2015, 3);
d = d2;
std::cout << d << " == " << d2 << std::endl;
date d3("2015.03.23");
std::cout << "d3++ == " << d3++ << std::endl;
std::cout << " d3 == " << d3 << std::endl;
std::cout << "++d3 == " << ++d3 << std::endl;
std::cout << " d3 == " << d3 << std::endl;
d3.setDate(2000,1,1);
std::cout << "d3.setDate(2000,1,1) == " << d3 << std::endl;
d3.setYear(2015).setMonth(3).setDay(23);
std::cout << "d3 == " << d3 << std::endl;
std::string s;
while( std::cin >> s )
{
try
{
std::cout << s << " == ";
date d4(s.c_str());
std::cout << d4 << std::endl;
}
catch( std::exception& e )
{
std::cerr << e.what() << std::endl;
}
}
return 0;
}
#ifndef DATE_H
#define DATE_H
#include <iostream>
#include <stdexcept>
class date
{
public:
class bad_date_t : public std::logic_error
{
public:
bad_date_t(const char *s) : std::logic_error(s) { }
};
date( int y, int m=1, int d=1) { setDate( y, m, d); }
date( const char *s);
int getYear() const { return year; }
int getMonth() const { return month; }
int getDay() const { return day; }
date& setYear( int y) { year = y; return *this; }
date& setMonth( int m) { month = m; return *this; }
date& setDay( int d) { day = d; return *this; }
void setDate( int y, int m, int d);
date& next();
date& add( int n);
date& operator++() { return next(); }
date operator++(int) { date curr(*this); next(); return curr; };
date& operator+=( int n) { return add(n); }
void get( std::istream& is);
void put( std::ostream& os) const;
private:
void checkDate( int y, int m, int d);
int year;
int month;
int day;
};
bool operator<( date d1, date d2);
inline bool operator==( date d1, date d2) { return !(d1<d2 || d2<d1); }
inline bool operator!=( date d1, date d2) { return d1<d2 || d2<d1; }
inline bool operator<=( date d1, date d2) { return !(d2<d1); }
inline bool operator>=( date d1, date d2) { return !(d1<d2); }
inline bool operator>( date d1, date d2) { return d2<d1; }
std::istream& operator>>( std::istream& is, date& d);
std::ostream& operator<<( std::ostream& os, const date &d);
#endif
#include <iostream>
#include <cstring>
#include <cstdlib>
#include "date.h"
using namespace std;
namespace
{
const int day_in_month[] =
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
}
date::date( const char *s)
{
const char *p1 = strchr( s, '.');
const char *p2 = strrchr( s, '.');
if ( p1 && p2 && p1 != p2 )
{
int y = atoi(s);
int m = atoi(p1+1);
int d = atoi(p2+1);
setDate( y, m, d);
}
else
{
throw bad_date_t("Wrong string");
}
}
void date::setDate( int y, int m, int d)
{
checkDate( y, m, d);
year = y;
month = m;
day = d;
}
date& date::next()
{
++day;
TODO
if ( day-1 == day_in_month[month-1])
{
day = 1;
++month;
}
if ( 13 == month )
{
month = 1;
++year;
}
return *this;
}
date& date::add( int n)
{
for (int i = 0; i < n; ++i)
{
next();
}
return *this;
}
void date::get( std::istream& is)
{
int y, m, d;
if ( is >> y >> m >> d )
{
setDate( y, m, d);
}
}
void date::put( std::ostream& os) const
{
os << "[ " << getYear() << "."
<< getMonth() << "."
<< getDay() << " ]";
}
void date::checkDate( int y, int m, int d)
{
if ( 0 == y ) throw bad_date_t("Bad year");
if ( m < 1 || m > 12 ) throw bad_date_t("Bad month");
if ( d < 1 || d > day_in_month[m-1] ) throw bad_date_t("Bad day");
}
bool operator<( date d1, date d2)
{
return (d1.getYear() < d2.getYear())
|| (d1.getYear() == d2.getYear() && d1.getMonth() < d2.getMonth())
|| (d1.getYear() == d2.getYear() && d1.getMonth() == d2.getMonth()
&& d1.getDay() < d2.getDay());
}
istream& operator>>( istream& is, date& d)
{
d.get( is);
return is;
}
ostream& operator<<( ostream& os, const date &d)
{
d.put( os);
return os;
}
# Components can be compile separatedly:
$ g++ -ansi -pedantic -Wall -c datemain.cpp
$ g++ -ansi -pedantic -Wall -c date.cpp
# then linked together:
$ g++ datemain.o date.o
# and run:
$ ./a.out