7. Наследяване
Производни класове
Базов клас - производен клас

Викане на конструктор на базов клас
#include "ccc_win.cpp"
#include "ccc_time.cpp"

/* This code is unchanged from chapter 8 */

const double PI = 3.141592653589793;

class Clock   {
public:
Clock() {}
Clock(Point c, double r){ center = c; radius = r; }
void set_time(Time t){ current_time = t; }
void draw() const;
private:
void draw_tick(double angle, double length) const;
void draw_hand(double angle, double length) const;
Time current_time;
Point center;
};

void Clock::draw_tick(double angle, double length) const
{
double alpha = PI / 2 - 6 * angle * PI / 180;
Point from(center.get_x() + cos(alpha)*radius*(1-length),
Point to(center.get_x() + cos(alpha) * radius,
center.get_y() + sin(alpha) * radius);
cwin << Line(from, to);
}

void Clock::draw_hand(double angle, double length) const
{
double alpha = PI / 2 - 6 * angle * PI / 180;
Point from = center;
Point to(center.get_x() + cos(alpha) * radius * length,
center.get_y() + sin(alpha) * radius * length);
cwin << Line(from, to);
}

void Clock::draw() const
{
cwin << Circle(center, radius);
int i;
const double HOUR_TICK_LENGTH = 0.2;
const double MINUTE_TICK_LENGTH = 0.1;
const double HOUR_HAND_LENGTH = 0.6;
const double MINUTE_HAND_LENGTH = 0.75;
for (i = 0; i < 12; i++)
{  draw_tick(i * 5, HOUR_TICK_LENGTH);
int j;
for (j = 1; j <= 4; j++)
draw_tick(i * 5 + j, MINUTE_TICK_LENGTH);
}
draw_hand(current_time.get_minutes(), MINUTE_HAND_LENGTH);
draw_hand((current_time.get_hours() +
current_time.get_minutes() / 60.0) * 5, HOUR_HAND_LENGTH);
}

/* This code extends the Clock code */

class WorldClock : public Clock {
public:
WorldClock() {}
WorldClock(string city_name, double hour_diff,
Point center, double radius);
void draw() const { Clock::draw(); cwin << city; }
private:
Message city;
};

WorldClock::WorldClock(string city_name, double hour_diff,
Point center, double radius) : Clock(center, radius)
{
Point p = center;
city = Message(p, city_name);
Time now;
const double SECONDS_PER_HOUR = 60 * 60;
set_time(now);
}

int main()
{  vector<WorldClock> clocks(6);

/* populate clocks */
clocks[0] = WorldClock("San Jose", 16, Point(-6.5, 5), 3);
clocks[1] = WorldClock("Taipei", 7, Point(0, 5), 3);
clocks[2] = WorldClock("Berlin", 1, Point(6.5, 5), 3);
clocks[3] = WorldClock("Cairo", 2, Point(-6.5, -5), 3);
clocks[4] = WorldClock("New York", 19, Point(0, -5), 3);
clocks[5] = WorldClock("Bombay", 4.5, Point(6.5, -5), 3);

int i;
for (i = 0; i < clocks.size(); i++) clocks[i].draw();
return 0;
}

Викане на член-функция на базов клас

Полиморфизъм

Виртуални функции

#include "ccc_win.cpp"
#include "ccc_time.cpp"

class WallClock  {
public:
WallClock() {}
WallClock(string city_name, double hour_diff,
Point c, double r);
virtual void draw() const;
Time get_time() const { return current_time; }
Point get_center() const { return center; }
double get_radius() const { return radius; }
private:
string city;
Time current_time;
Point center;
};

class AnalogClock : public WallClock  {
public:
AnalogClock() {}
AnalogClock(string city_name, double hour_diff,
Point c, double r);
virtual void draw() const;
private:
void draw_hand(double angle, double length) const;
};

class DigitalClock : public WallClock  {
public:
DigitalClock(); {}
DigitalClock(string city_name, double hour_diff,
Point c, double r, bool am_pm);
virtual void draw() const;
private:
bool use_am_pm;
};

const double PI = 3.141592653589793;
string int_to_string(int n)
{
ostringstream outstr;
outstr << n;
return outstr.str();
}

string time_to_string(int hours, int minutes, bool am_pm)
{
string suffix;
if (am_pm)
{  if (hours < 12)  suffix = "am";
else             suffix = "pm";
hours = hours - 12;
if (hours == 0) hours = 12;
}
string result = int_to_string(hours) + ":";
if (minutes < 10) result = result + "0";
result = result + int_to_string(minutes);
if (am_pm) result = result + " " + suffix;
return result;
}

WallClock::WallClock(string city_name, double hour_diff,
Point c, double r)
{
city = city_name;
center = c;
const double SECONDS_PER_HOUR = 60 * 60;
}

void WallClock::draw() const
{
Point p = center;
cwin << Message(p, city);
}

AnalogClock::AnalogClock(string city_name, double hour_diff,
Point c, double r)
: WallClock(city_name, hour_diff, c, r) {}

void AnalogClock::draw_hand(double angle, double length) const
{
double alpha = PI / 2 - 6 * angle * PI / 180;
Point from = get_center();
Point to = from;
to.move(cos(alpha) * get_radius() * length,
sin(alpha) * get_radius() * length);
cwin << Line(from, to);
}

void AnalogClock::draw() const
{  WallClock::draw();
cwin << Circle(get_center(), get_radius());
const double HOUR_HAND_LENGTH = 0.6;
const double MINUTE_HAND_LENGTH = 0.75;
draw_hand(get_time().get_minutes(), MINUTE_HAND_LENGTH);
draw_hand((get_time().get_hours() +
get_time().get_minutes() / 60.0) * 5, HOUR_HAND_LENGTH);
}

DigitalClock::DigitalClock(string city_name, double hour_diff, Point c, double r, bool am_pm)
: WallClock(city_name, hour_diff, c, r)
{  use_am_pm = am_pm;   }

void DigitalClock::draw() const
{  WallClock::draw();
string time;
int hours = get_time().get_hours();
int minutes = get_time().get_minutes();
cwin << Message(get_center(), time_to_string(hours, minutes, use_am_pm));
}

int main()
{  vector<WallClock*> clocks(6);

/* populate clocks */
clocks[0] = new DigitalClock("San Jose",16,Point(-6.5,5), 3, false);
clocks[1] = new AnalogClock("Taipei",7, Point(0,5), 3);
clocks[2] = new AnalogClock("Berlin",1, Point(6.5,5), 3);
clocks[3] = new AnalogClock("Cairo",2, Point(-6.5,-5), 3);
clocks[4] = new DigitalClock("New York",19, Point(0,-5), 3, true);
clocks[5] = new AnalogClock("Bombay",4.5, Point(6.5,-5), 3);

int i;
for (i = 0; i < clocks.size(); i++) (*clocks[i]).draw();
return 0;
}

Връзки между класовете
Две основни връзки: връзка "е" и връзка "има", реализирани чрез наследственост и включване (агрегация).
class Car: public Vehicle
{ ...
private:
vector<Tire> tires;
...
};