diff --git a/13-class_inheritance/review/review.md b/13-class_inheritance/review/review.md index fa37a02456086c1a179ee208f0a440ba2ff03919..a35a389876158e876f6763bdde66aabcacb47ab4 100644 --- a/13-class_inheritance/review/review.md +++ b/13-class_inheritance/review/review.md @@ -298,3 +298,53 @@ C++11 支持将关键字 `explicit` 用于转换函数。与构造函数一样 按引用传递对象的另一个原因是,在继承使用虚函数时,被定义为接受基类引用参数的函数可以接受派生类。 ##### 2.5. 返回对象和返回引用 +首先,在编码方面,直接返回对象与返回引用之间唯一的区别在于函数原型和函数头: +```cpp +Star nova1(const Star &); // returns a Star object +Star &nova2(const Star &); // returns a reference to a Star +``` +其次,应返回引用而不是返回对象的原因在于,返回对象涉及生成返回对象的临时副本,这是调用函数的程序可以使用的副本。因此,返回对象的时间成本包括调用复制构造函数来生成副本所需的时间和调用析构函数删除副本所需的时间。返回引用可节省时间和内存。直接返回对象与按值传递对象相似:它们都生成临时副本。同样,返回引用与按引用传递对象相似:调用和被调用的函数对同一个对象进行操作。 + +然而,并不是总是可以返回引用。函数不能返回在函数中创建的临时对象的引用,因为当函数结束时,临时对象将消失,因此这种引用将是非法的。在这种情况下,因返回对象,以生成一个调用程序可以使用的副本。 + +通用的规则是,如果函数返回是在函数中创建的临时对象的引用,则不要使用引用。例如,下面的方法使用构造函数来创建一个新对象,然后返回该对象的副本: +```cpp +Vector Vector::operator+(const Vector &b) const +{ + return Vector(x + b.x, y + b.y); +} +``` +如果函数返回的是通过引用传递给它的对象,则应按引用返回对象。例如,下面的代码按引用返回调用函数的对象或作为参数传递给函数的对象: +```cpp +const Stock &Stock::topval(const Stock &s) const +{ + if (s.total_val > total_val) + return s; // argument object + else + return *this // invoking object +} +``` + +##### 2.6 使用 `const` +使用 `const` 时应特别注意。可以用它来确保方法不修改参数: +```cpp +Star::Star(const char *s) {...} // won't change the string to switch s points +``` +可以使用 `const` 来确保方法不修改调用它的对象: +```cpp +void Star::show() const {...} // won't change invoking object +``` +这里 `const` 表示 `const Star *this`, 而 `this` 指向调用的对象。 +通常,可以将返回引用的函数放在赋值语句的左侧,这实际上意味着可以将值赋给引用的对象。但可以使用 `const` 来确保引用或指针返回的值不能用于修改对象中的数据: +```cpp +const Stock &Stock::topva(const Stock &s) const +{ + if (s.total_val > total_val) + return s; // argument object + else + return *this; // invoking object +} +``` +该方法返回对 `*this` 或 `s` 的引用。因为 `*this` 和 `s` 都被声明为 `const`, 所以函数不能对它们进行修改,这意味着返回的引用也必须被声明为 `const`。 + +注意,如果函数将参数声明为指向 `const` 的引用或指针,则不能将该参数传递给另一个函数,除非后者也确保了参数不会被修改。 diff --git a/14-reusing_code_in_cpp/student/studentc.cpp b/14-reusing_code_in_cpp/student/studentc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..75b06493f07b362ec3f73289db10eb85ba381606 --- /dev/null +++ b/14-reusing_code_in_cpp/student/studentc.cpp @@ -0,0 +1,61 @@ +#include "studentc.h" + +double Student::Average() const +{ + if (score.size() > 0) + return score.sum() / score.size(); + else + return 0; +} + +const string &Student::Name() const +{ + return name; +} + +double &Student::operator[](int n) +{ + return score[n]; +} + +double Student::operator[](int n) const +{ + return score[n]; +} + +istream &operator>>(istream &is, Student &stu) +{ + is >> stu.name; + return is; +} + +istream &getline(istream &is, Student &stu) +{ + getline(is, stu.name); + return is; +} + +ostream &operator<<(ostream &os, const Student &stu) +{ + int i = 0; + os << "Scores for " << stu.name << ": " << endl; + + int lim = stu.score.size(); + + if (lim > 0) + { + for (i = 0; i < lim; i++) + { + os << stu.score[i] << " "; + if (i % 5 == 4) + os << endl; + } + + if (i % 5 != 0) + os << endl; + } + else + os << "Empty array!" << endl; + + return os; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student/studentc.h b/14-reusing_code_in_cpp/student/studentc.h index 157c577cc2c62dadce00fc5a67394e90fe0ab4ac..b654a309e3129c6584741d13a5f52a2d9846bbf8 100644 --- a/14-reusing_code_in_cpp/student/studentc.h +++ b/14-reusing_code_in_cpp/student/studentc.h @@ -11,13 +11,13 @@ class Student private: typedef valarray ArrayDb; string name; - ArrayDb score; // valarray scores; + ArrayDb score; // valarray scores; public: Student() : name("Null Student"), score() {} explicit Student(const std::string &s) : name(s), score() {} explicit Student(int n) : name("Nully"), score(n) {} Student(const string &s, int n) : name(s), score(n) {} - Student(const string &s, const ArrayDB &a) : name(s), score(a) {} + Student(const string &s, const ArrayDb &a) : name(s), score(a) {} Student(const string &s, const double *pd, int n) : name(s), score(pd, n) {} ~Student() {} double Average() const; @@ -29,5 +29,5 @@ public: friend istream &getline(istream &is, Student &stu); friend ostream &operator<<(ostream &os, const Student &stu); }; - + #endif \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student/usestudentc.cpp b/14-reusing_code_in_cpp/student/usestudentc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..102783a862c25f8f21a4ec15936fdb3117745c85 --- /dev/null +++ b/14-reusing_code_in_cpp/student/usestudentc.cpp @@ -0,0 +1,43 @@ +#include +#include "studentc.h" + +using namespace std; + +const int pupils = 3; +const int quizzes = 5; + +void set(Student &stu, int n); + +int main() +{ + Student ada[pupils] = {Student(quizzes), Student(quizzes), Student(quizzes)}; + + int i; + for (i = 0; i < pupils; i++) + set(ada[i], quizzes); + + cout << "\nStudent list: " << endl; + for (i = 0; i < pupils; i++) + cout << ada[i].Name() << endl; + + cout << "\nResut list: " << endl; + for (i = 0; i < pupils; i++) + { + cout << ada[i]; + cout << "Average: " << ada[i].Average() << endl; + } + + return 0; +} + +void set(Student &stu, int n) +{ + cout << "Please enter the student's name: "; + getline(cin, stu); + cout << "Please enter: " + << " quiz scores: " << endl; + for (int i = 0; i < n; i++) + cin >> stu[i]; + while (cin.get() != '\n') + ; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student1/studentc.cpp b/14-reusing_code_in_cpp/student1/studentc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c7423d40f372d61caa498186a2bc13419951791b --- /dev/null +++ b/14-reusing_code_in_cpp/student1/studentc.cpp @@ -0,0 +1,67 @@ +#include "studentc.h" + +double Student::Average() const +{ + if (ArrayDb::size() > 0) + return ArrayDb::sum() / ArrayDb::size(); + else + return 0; +} + +const string &Student::Name() const +{ + return (const string &) *this; +} + +double &Student::operator[](int n) +{ + return ArrayDb::operator[](n); +} + +double Student::operator[](int n) const +{ + return ArrayDb::operator[](n); +} + +istream &operator>>(istream &is, Student &stu) +{ + is >> (string &)stu; + return is; +} + +istream &getline(istream &is, Student &stu) +{ + getline(is, (string &)stu); + return is; +} + +ostream &Student::arr_out(ostream &os) const +{ + int i = 0; + int lim = ArrayDb::size(); + + if (lim > 0) + { + for (i = 0; i < lim; i++) + { + os << ArrayDb::operator[](i) << " "; + if (i % 5 == 4) + os << endl; + } + + if (i % 5 != 0) + os << endl; + } + else + os << "Empty array!" << endl; + + return os; +} + +ostream &operator<<(ostream &os, const Student &stu) +{ + os << "Scores for " << (const string &)stu << ": " << endl; + stu.arr_out(os); + + return os; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student1/studentc.h b/14-reusing_code_in_cpp/student1/studentc.h new file mode 100644 index 0000000000000000000000000000000000000000..cee05a4f371a5f6e228ec61b6ac4a44c336f223b --- /dev/null +++ b/14-reusing_code_in_cpp/student1/studentc.h @@ -0,0 +1,34 @@ +#ifndef __STUDENTC_H__ +#define __STUDENTC_H__ + +#include +#include +#include +using namespace std; + +class Student : private string, private valarray +{ +private: + typedef valarray ArrayDb; + // string name; + // ArrayDb score; // valarray scores; + ostream &arr_out(ostream &os) const; +public: + Student() : string("Null Student"), ArrayDb() {} + explicit Student(const std::string &s) : string(s), ArrayDb() {} + explicit Student(int n) : string("Nully"), ArrayDb(n) {} + Student(const string &s, int n) : string(s), ArrayDb(n) {} + Student(const string &s, const ArrayDb &a) : string(s), ArrayDb(a) {} + Student(const string &s, const double *pd, int n) : string(s), ArrayDb(pd, n) {} + ~Student() {} + double Average() const; + const string &Name() const; + double &operator[](int n); // stu[0] = 100; + double operator[](int n) const; // a = stu[0]; + + friend istream &operator>>(istream &is, Student &stu); + friend istream &getline(istream &is, Student &stu); + friend ostream &operator<<(ostream &os, const Student &stu); +}; + +#endif \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student1/usestudentc.cpp b/14-reusing_code_in_cpp/student1/usestudentc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..102783a862c25f8f21a4ec15936fdb3117745c85 --- /dev/null +++ b/14-reusing_code_in_cpp/student1/usestudentc.cpp @@ -0,0 +1,43 @@ +#include +#include "studentc.h" + +using namespace std; + +const int pupils = 3; +const int quizzes = 5; + +void set(Student &stu, int n); + +int main() +{ + Student ada[pupils] = {Student(quizzes), Student(quizzes), Student(quizzes)}; + + int i; + for (i = 0; i < pupils; i++) + set(ada[i], quizzes); + + cout << "\nStudent list: " << endl; + for (i = 0; i < pupils; i++) + cout << ada[i].Name() << endl; + + cout << "\nResut list: " << endl; + for (i = 0; i < pupils; i++) + { + cout << ada[i]; + cout << "Average: " << ada[i].Average() << endl; + } + + return 0; +} + +void set(Student &stu, int n) +{ + cout << "Please enter the student's name: "; + getline(cin, stu); + cout << "Please enter: " + << " quiz scores: " << endl; + for (int i = 0; i < n; i++) + cin >> stu[i]; + while (cin.get() != '\n') + ; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student2/studentc.cpp b/14-reusing_code_in_cpp/student2/studentc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4ab314d3c8ad05b890544c360350ae5c9759030 --- /dev/null +++ b/14-reusing_code_in_cpp/student2/studentc.cpp @@ -0,0 +1,83 @@ +#include "studentc.h" + +double Student::Average() const +{ + if (ArrayDb::size() > 0) + return ArrayDb::sum() / ArrayDb::size(); + else + return 0; +} + +const string &Student::Name() const +{ + return (const string &) *this; +} + +double &Student::operator[](int n) +{ + return ArrayDb::operator[](n); +} + +double Student::operator[](int n) const +{ + return ArrayDb::operator[](n); +} + +istream &operator>>(istream &is, Student &stu) +{ + is >> (string &)stu; + return is; +} + +istream &getline(istream &is, Student &stu) +{ + getline(is, (string &)stu); + return is; +} + +// ostream &Student::arr_out(ostream &os) const +// { +// int i = 0; +// int lim = ArrayDb::size(); + +// if (lim > 0) +// { +// for (i = 0; i < lim; i++) +// { +// os << ArrayDb::operator[](i) << " "; +// if (i % 5 == 4) +// os << endl; +// } + +// if (i % 5 != 0) +// os << endl; +// } +// else +// os << "Empty array!" << endl; + +// return os; +// } + +ostream &operator<<(ostream &os, const Student &stu) +{ + int i = 0; + os << "Scores for " << (const string &)stu << ": " << endl; + int lim = stu.size(); + + if (lim > 0) + { + for (i = 0; i < lim; i++) + { + os << stu.operator[](i) << " "; + if (i % 5 == 4) + os << endl; + } + + if (i % 5 != 0) + os << endl; + } + else + os << "Empty array!" << endl; + + return os; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student2/studentc.h b/14-reusing_code_in_cpp/student2/studentc.h new file mode 100644 index 0000000000000000000000000000000000000000..c54fb23850c5fb29d10ce42fb9d5ec2ea1d13ab7 --- /dev/null +++ b/14-reusing_code_in_cpp/student2/studentc.h @@ -0,0 +1,36 @@ +#ifndef __STUDENTC_H__ +#define __STUDENTC_H__ + +#include +#include +#include +using namespace std; + +class Student : private string, private valarray +{ +private: + typedef valarray ArrayDb; + // string name; + // ArrayDb score; // valarray scores; + // ostream &arr_out(ostream &os) const; +public: + using valarray::size; + using valarray::operator[]; + Student() : string("Null Student"), ArrayDb() {} + explicit Student(const std::string &s) : string(s), ArrayDb() {} + explicit Student(int n) : string("Nully"), ArrayDb(n) {} + Student(const string &s, int n) : string(s), ArrayDb(n) {} + Student(const string &s, const ArrayDb &a) : string(s), ArrayDb(a) {} + Student(const string &s, const double *pd, int n) : string(s), ArrayDb(pd, n) {} + ~Student() {} + double Average() const; + const string &Name() const; + double &operator[](int n); // stu[0] = 100; + double operator[](int n) const; // a = stu[0]; + + friend istream &operator>>(istream &is, Student &stu); + friend istream &getline(istream &is, Student &stu); + friend ostream &operator<<(ostream &os, const Student &stu); +}; + +#endif \ No newline at end of file diff --git a/14-reusing_code_in_cpp/student2/usestudentc.cpp b/14-reusing_code_in_cpp/student2/usestudentc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..102783a862c25f8f21a4ec15936fdb3117745c85 --- /dev/null +++ b/14-reusing_code_in_cpp/student2/usestudentc.cpp @@ -0,0 +1,43 @@ +#include +#include "studentc.h" + +using namespace std; + +const int pupils = 3; +const int quizzes = 5; + +void set(Student &stu, int n); + +int main() +{ + Student ada[pupils] = {Student(quizzes), Student(quizzes), Student(quizzes)}; + + int i; + for (i = 0; i < pupils; i++) + set(ada[i], quizzes); + + cout << "\nStudent list: " << endl; + for (i = 0; i < pupils; i++) + cout << ada[i].Name() << endl; + + cout << "\nResut list: " << endl; + for (i = 0; i < pupils; i++) + { + cout << ada[i]; + cout << "Average: " << ada[i].Average() << endl; + } + + return 0; +} + +void set(Student &stu, int n) +{ + cout << "Please enter the student's name: "; + getline(cin, stu); + cout << "Please enter: " + << " quiz scores: " << endl; + for (int i = 0; i < n; i++) + cin >> stu[i]; + while (cin.get() != '\n') + ; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/worker/useworker.cpp b/14-reusing_code_in_cpp/worker/useworker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4137e4c685c76b0fd56c2903d0126a991678ffda --- /dev/null +++ b/14-reusing_code_in_cpp/worker/useworker.cpp @@ -0,0 +1,25 @@ +#include +#include "worker.h" + +const int LIM = 4; + +int main() +{ + Waiter bob("Bob", 314, 5); + Singer bev("Bev", 522, 3); + Waiter w_temp; + Singer s_temp; + + Worker *pw[LIM] = {&bob, &bev, &w_temp, &s_temp}; + + int i; + for (i = 2; i< LIM; i++) + pw[i]->Set(); + + for (i = 0; i < LIM; i++) + { + pw[i]->Show(); + } + + return 0; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/worker/worker.cpp b/14-reusing_code_in_cpp/worker/worker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..db6e85314c493ed00e6859c366cbe5ba9d672a25 --- /dev/null +++ b/14-reusing_code_in_cpp/worker/worker.cpp @@ -0,0 +1,57 @@ +#include "worker.h" + +void Worker::Set() +{ + cout << "Enter worker's fullname: "; + getline(cin, fullname); + cout << "Enter worker's ID: "; + cin >> id; + while (cin.get() != '\n'); +} + +void Worker::Show() const +{ + cout << "Name: " << fullname << endl; + cout << "Employee ID: " << id << endl; +} + +void Waiter::Set() +{ + Worker::Set(); + cout << "Enter waiter's panache rating: "; + cin >> panache; + while (cin.get() != '\n'); +} + +void Waiter::Show() const +{ + Worker::Show(); + cout << "Panache rating: " << panache << endl; +} + +const char *Singer::pv[] = {"other", "alto", "contralto", "soprano", "bass", "baritone", "tenor"}; + +void Singer::Set() +{ + Worker::Set(); + int i; + for (i = 0; i < Vtypes; i++) + { + cout << i << ": " << pv[i] << " "; + if (i % 4 == 3) + cout << endl; + } + + if (i % 4 != 0) + cout << endl; + + cout << "Please enter a value >= 0 and < " << Vtypes << endl; + cin >> voice; + while (cin.get() != '\n'); +} + +void Singer::Show() const +{ + Worker::Show(); + cout << "Voice range: " << pv[voice] << endl; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/worker/worker.h b/14-reusing_code_in_cpp/worker/worker.h new file mode 100644 index 0000000000000000000000000000000000000000..a1d2c55dc9477e8774ab3ae134db8b0e52561e33 --- /dev/null +++ b/14-reusing_code_in_cpp/worker/worker.h @@ -0,0 +1,63 @@ +#ifndef __WORKER_H__ +#define __WORKER_H__ + +#include +#include +using namespace std; + +class Worker +{ +private: + string fullname; + long id; + +public: + Worker() : fullname("none one"), id(0) {} + Worker(const string &s, long n) : fullname(s), id(n) {} + virtual ~Worker() {} + virtual void Set(); + virtual void Show() const; +}; + +class Waiter : public Worker +{ +private: + int panache; + +public: + Waiter() : Worker(), panache(0){}; + Waiter(const string &s, long n, int p = 0) : Worker(s, n), panache(p) {} + Waiter(const Worker &wk, int p = 0) : Worker(wk), panache(p) {} + void Set(); + void Show() const; +}; + +class Singer : public Worker +{ +protected: + enum + { + other, + alto, + contralto, + soprano, + bass, + baritone, + tenor + }; + enum + { + Vtypes = 7 + }; + +public: + static const char *pv[Vtypes]; + int voice; + Singer() : Worker(), voice(other) {} + Singer(const string &s, long n, int v = other) : Worker(s, n), voice(v) {} + Singer(const Worker &wk, int v = other) : Worker(wk), voice(v) {} + void Set(); + void Show() const; +}; + +#endif \ No newline at end of file diff --git a/14-reusing_code_in_cpp/worker1/useworker.cpp b/14-reusing_code_in_cpp/worker1/useworker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae28fa8e5162e8d744fa40bd8d6ef95d38345250 --- /dev/null +++ b/14-reusing_code_in_cpp/worker1/useworker.cpp @@ -0,0 +1,57 @@ +#include +#include +#include "worker.h" + +const int SIZE = 3; + +int main() +{ + Worker *lolas[SIZE]; + + int i; + for (i = 0; i < SIZE; i++) + { + char choice; + cout << "Enter the employee category: " << endl + << "w: waiter s: singer t: sining waiter q:quit" << endl; + cin >> choice; + + while (strchr("wstq", choice) == NULL) + { + cout << "Please enter a, w, s, t, q: "; + cin >> choice; + } + + if (choice == 'q') + break; + switch (choice) + { + case 'w': + lolas[i] = new Waiter; + break; + case 's': + lolas[i] = new Singer; + break; + case 't': + lolas[i] = new SingingWaiter; + break; + default: + break; + } + + while (cin.get() != '\n'); + lolas[i]->Set(); + } + + cout << "\nHere is your staff: " << endl; + for (i = 0; i < SIZE; i++) + { + lolas[i]->Show(); + cout << endl; + } + + for (i = 0; i < SIZE; i++) + delete lolas[i]; + + return 0; +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/worker1/worker.cpp b/14-reusing_code_in_cpp/worker1/worker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..18cc0da4fd6042ac071b1fd88a6e42773e866881 --- /dev/null +++ b/14-reusing_code_in_cpp/worker1/worker.cpp @@ -0,0 +1,91 @@ +#include "worker.h" + +void Worker::Get() +{ + cout << "Enter worker's fullname: "; + getline(cin, fullname); + cout << "Enter worker's ID: "; + cin >> id; + while (cin.get() != '\n'); +} + +void Worker::Data() const +{ + cout << "Name: " << fullname << endl; + cout << "Employee ID: " << id << endl; +} + +void Waiter::Get() +{ + cout << "Enter waiter's panache rating: "; + cin >> panache; + while (cin.get() != '\n'); +} + +void Waiter::Data() const +{ + cout << "Panache rating: " << panache << endl; +} + +void Waiter::Set() +{ + Worker::Get(); + Get(); +} + +void Waiter::Show() const +{ + Worker::Data(); + Data(); +} + +const char *Singer::pv[] = {"other", "alto", "contralto", "soprano", "bass", "baritone", "tenor"}; + +void Singer::Get() +{ + int i; + for (i = 0; i < Vtypes; i++) + { + cout << i << ": " << pv[i] << " "; + if (i % 4 == 3) + cout << endl; + } + + if (i % 4 != 0) + cout << endl; + + cout << "Please enter a value >= 0 and < " << Vtypes << endl; + cin >> voice; + while (cin.get() != '\n'); +} + +void Singer::Data() const +{ + cout << "Voice range: " << pv[voice] << endl; +} + +void Singer::Set() +{ + Worker::Get(); + Get(); +} + +void Singer::Show() const +{ + Worker::Data(); + Data(); +} + +void SingingWaiter::Set() +{ + Worker::Get(); + Waiter::Get(); + Singer::Get(); +} + +void SingingWaiter::Show() const +{ + Worker::Data(); + Waiter::Data(); + Singer::Data(); +} \ No newline at end of file diff --git a/14-reusing_code_in_cpp/worker1/worker.h b/14-reusing_code_in_cpp/worker1/worker.h new file mode 100644 index 0000000000000000000000000000000000000000..d5b1494074a3cc8867b97de205e622a4d4a630a9 --- /dev/null +++ b/14-reusing_code_in_cpp/worker1/worker.h @@ -0,0 +1,82 @@ +#ifndef __WORKER_H__ +#define __WORKER_H__ + +#include +#include +using namespace std; + +class Worker +{ +private: + string fullname; + long id; + +protected: + virtual void Data() const; + virtual void Get(); +public: + Worker() : fullname("none one"), id(0) {} + Worker(const string &s, long n) : fullname(s), id(n) {} + virtual ~Worker() {} + virtual void Set() = 0; + virtual void Show() const = 0; +}; + +class Waiter : virtual public Worker +{ +private: + int panache; +protected: + void Data() const; + void Get(); +public: + Waiter() : Worker(), panache(0){}; + Waiter(const string &s, long n, int p = 0) : Worker(s, n), panache(p) {} + Waiter(const Worker &wk, int p = 0) : Worker(wk), panache(p) {} + void Set(); + void Show() const; +}; + +class Singer : public virtual Worker +{ +protected: + enum + { + other, + alto, + contralto, + soprano, + bass, + baritone, + tenor + }; + enum + { + Vtypes = 7 + }; + void Data() const; + void Get(); +public: + static const char *pv[Vtypes]; + int voice; + Singer() : Worker(), voice(other) {} + Singer(const string &s, long n, int v = other) : Worker(s, n), voice(v) {} + Singer(const Worker &wk, int v = other) : Worker(wk), voice(v) {} + void Set(); + void Show() const; +}; + +class SingingWaiter : public Waiter, public Singer +{ +protected: + void Data() const {}; + void Get() {}; +public: + SingingWaiter() {}; + SingingWaiter(const string &s, long n, int p = 0, int v = other) : Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {} + SingingWaiter(const Worker &wk, long p = 0, int v = other) : Worker(wk), Waiter(wk, p), Singer(wk, v) {} + void Set(); + void Show() const; +}; + +#endif \ No newline at end of file