|
|
Employee - базов
клас, Manager -
производен клас
- членовете на базовият клас са членове и на производния клас
(всеки обект от производния клас съдържа данните на базовия клас);
- функциите на производният клас нямат достъп до частните
членове на базовия клас .
Дефиниции на
функции от производния клас.
Конструкторът на производния клас има две
задачи:
- да инициализира полетата с данни;
- да инициализира обекта от базовия клас, който се съдържа в
производния клас.
Manager::Manager(string n,
double sal, string dept)
:
Employee(n, sal)
{ department = dept; }
Ако в базовия и в производния класове има
функции с едно и също име, то викането на член-функция на базовия
клас от функция на производния клас става с помощта на операция
"принадлежност към клас" - ::
void Manager::print()
{ Employee::print();
cout <<
department; }
// clock1.cpp}
#include <iostream> #include <iomanip> #include <string> using namespace std; #include "ccc_time.h" class Clock { public: /** Constructs a clock that can tell the local time. @param use_military true if the clock uses military format (21:05) and
flase if the clock uses "am/pm" format (9:05 pm) */ Clock(bool use_military); /** Gets the location of this clock. @return the location */ string get_location() const; /** Gets the hours of this clock. @return the hours, in military or am/pm format */ int get_hours() const; /** Gets the minutes of this clock. @return the minutes */ int get_minutes() const; /** Checks whether this clock uses miltary format. @return true if miltary format */ bool is_military() const; private: bool military; }; Clock::Clock(bool use_military) { military = use_military; } string Clock::get_location() const { return "Local"; } int Clock::get_hours() const { Time now; int hours = now.get_hours(); if (military) return hours; if (hours == 0) return 12; else if (hours > 12) return hours - 12; else return hours; } int Clock::get_minutes() const { Time now; return now.get_minutes(); } bool Clock::is_military() const { return military; } int main() { Clock clock1(true); Clock clock2(false); bool more = true; while (more) { cout << "Military time: " << clock1.get_hours() << ":" << setw(2) << setfill('0')
<< clock1.get_minutes()
<< setfill(' ') << "\n"; cout << "am/pm time: " << clock2.get_hours() << ":" << setw(2) << setfill('0')
<< clock2.get_minutes()
<< setfill(' ') << "\n"; cout << "Try again? (y/n) "; string input; getline(cin, input); if (input != "y") more = false; } return 0;
TravelClock clock("London", -2);Обект от TravelClock има 3 разлики с обект от Clock:
cout << "The time in " << clock.get_location() << " is "
<< clock.get_hours() << ":" << clock.get_minutes();
class TravelClock : public Clock {Конструкторът на производния клас има две задачи:
public:
TravelClock(bool mil, string loc, double off);
int get_hours() const;
string get_location() const;
private:
string location;
int time_difference;
};
TravelClock::TravelClock(bool mil, string loc, int diff)Ако не се извика конструктора на базовия клас, обектът от производния клас се създава като автоматично (неявно) се вика конструктора по подразбиране на базовия клас. Ако такъв конструктор няма, то задължително трябва да вика явно конструктора на базовия клас.
: Clock(mil)
{ location = loc;
time_difference = diff;
while (time_difference < 0)
time_difference = time_difference + 24;
};
int TravelClock::get_hours() constДанните на базовия клас (military) не са достъпни от член-функциите на производния клас.
{ . . .
int h = Clock::get_hours(); /* calls base-class function */
. . .
}
// clock2.cpp
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
#include "ccc_time.h"
class Clock {
public:
Clock(bool use_military);
string get_location() const;
int get_hours() const;
int get_minutes() const;
bool is_military() const;
private:
bool military;
};
Clock::Clock(bool use_military)
{ military = use_military; }
string Clock::get_location() const
{ return "Local"; }
int Clock::get_hours() const
{ Time now;
int hours = now.get_hours();
if (military) return hours;
if (hours == 0) return 12;
else if (hours > 12) return hours - 12;
else return hours;
}
int Clock::get_minutes() const
{ Time now;
return now.get_minutes();
}
bool Clock::is_military() const
{ return military; }
class TravelClock : public Clock {
public:
/**
Constructs a travel clock that can tell the time
at a specified location
@param mil true if the clock uses military format
@param loc the location
@param diff the time difference from the local time
*/
TravelClock(bool mil, string loc, int diff);
string get_location() const;
int get_hours() const;
private:
string location;
int time_difference;
};
TravelClock::TravelClock(bool mil, string loc, int diff)
: Clock(mil)
{ location = loc;
time_difference = diff;
while (time_difference < 0)
time_difference = time_difference + 24;
}
string TravelClock::get_location() const
{ return location; }
int TravelClock::get_hours() const
{ int h = Clock::get_hours();
if (is_military())
return (h + time_difference) % 24;
else
{ h = (h + time_difference) % 12;
if (h == 0) return 12;
else return h;
}
}
int main()
{ Clock clock1(true);
TravelClock clock2(true, "Rome", -1);
TravelClock clock3(false, "Tokyo", 5);
cout << clock1.get_location() << " time: "
<< clock1.get_hours() << ":"
<< setw(2) << setfill('0')
<< clock1.get_minutes()
<< setfill(' ') << "\n";
cout << clock2.get_location() << " time: "
<< clock2.get_hours() << ":"
<< setw(2) << setfill('0')
<< clock2.get_minutes()
<< setfill(' ') << "\n";
cout << clock3.get_location() << " time: "
<< clock3.get_hours() << ":"
<< setw(2) << setfill('0')
<< clock3.get_minutes()
<< setfill(' ') << "\n";
return 0;
}
vector<Clock> clocks(3);Тъй като обект от производния клас е обект и от базовия клас, то можем да използваме операция присвояване с ляв аргумент обект от Clock и десен аргумент - обект от TravelClock. Ефектът обаче е отрязване на даните, дефинирани в производния клас, т.е. на location и time_difference.
/* populate clocks */
clocks[0] = Clock(true);
clocks[1] = TravelClock(true, "Rome", -1);
clocks[2] = TravelClock(false, "Tokyo", 5);
for (int i = 0; i < clocks.size(); i++)
cout << clocks[i].get_location() << " time: "
<< clocks[i].get_hours() << ":"
<< setw(2) << setfill('0')
<< clocks[i].get_minutes()
<< setfill(' ') << "\n";
vector<Clock*> clocks(3);Векторът clocks съдържа колекция от различни часовници. Такава колекция се нарича полиморфна.
/* populate clocks */
clocks[0] = new Clock(true);
clocks[1] = new TravelClock(true, "Rome", -1);
clocks[2] = new TravelClock(false, "Tokyo", 5);
for (int i = 0; i < clocks.size(); i++)
cout << clocks[i]->get_location() << " time: "
<< clocks[i]->get_hours() << ":"
<< setw(2) << setfill('0')
<< clocks[i]->get_minutes()
<< setfill(' ') << "\n";
Local time is 21:15защото указателите са от базовия клас и съответно с тях се вика функция от същия клас. Това свързване на обект (неявен параметър) и член-функция се нарича статично свързване. В С++ може да се реализира и динамично свързване - когато се вика функция от класа, от който е обектът, към който сочи указателя. За това динамично свързване е необходимо функциите да се обяват като виртуални.
Local time is 21:15
Local time is 9:15
class Clock {Ето реализация на цялата програма с динамично свързване:
public:
Clock(bool use_military);
virtual string get_location() const;
virtual int get_hours() const;
int get_minutes() const;
bool is_military() const;
private:
. . .
};
// clock3.cpp
#include <iostream> #include <iomanip> #include <string> #include <vector> using namespace std; #include "ccc_time.h" class Clock { public: Clock(bool use_military); virtual string get_location() const; virtual int get_hours() const; int get_minutes() const; bool is_military() const; private: bool military; }; Clock::Clock(bool use_military) { military = use_military; } string Clock::get_location() const { return "Local"; } int Clock::get_hours() const { Time now; int hours = now.get_hours(); if (military) return hours; if (hours == 0) return 12; else if (hours > 12) return hours - 12; else return hours; } int Clock::get_minutes() const { Time now; return now.get_minutes(); } bool Clock::is_military() const { return military; } class TravelClock : public Clock { public: TravelClock(bool mil, string loc, int diff); string get_location() const; int get_hours() const; private: string location; int time_difference; }; TravelClock::TravelClock(bool mil, string loc, int diff) : Clock(mil) { location = loc; time_difference = diff; while (time_difference < 0)
time_difference = time_difference + 24; } string TravelClock::get_location() const { return location; } int TravelClock::get_hours() const { int h = Clock::get_hours(); if (is_military()) return (h + time_difference) % 24; else { h = (h + time_difference) % 12; if (h == 0) return 12; else return h; } } int main() { vector<Clock*> clocks(3); clocks[0] = new Clock(true); clocks[1] = new TravelClock(true, "Rome", -1); clocks[2] = new TravelClock(false, "Tokyo", 5); for (int i = 0; i < clocks.size(); i++) { cout << clocks[i]->get_location() << " time: "
<< clocks[i]->get_hours() << ":" << setw(2) << setfill('0')
<< clocks[i]->get_minutes()
<< setfill(' ') << "\n"; } return 0; }