• C++ Primer Plus第十三章编程练习答案


    1,以下面的类声明为基础:

    // base class
    class Cd{ // represents a CD disk

    private:
    char performers[50] ;
    char label[20];
    int selections;// number of selections

    double playtime; // playing time in minutes

    public:
    Cd(char * sl,char * s2,int n,double x!;Cd(const cd & d!;
    Cd{};
    -Cd(};
    void Report() const; // reports all CD data

    Cd & operator=(const cd & d);

    派生出一个Classic 类,并添加一组 har 成员,用于存储指出CD 中主要作品的字符串。修改上述声明,使基类的所有函数都是虚的。如果上述定义声明的某个方法并不需要,则请删除它。使用下面的程序测试您的产品:

    #include
    using namespace std;
    #include "classic.h"// which will contain #include cd.hvoid Bravo(const Cd & disk);int main()
    Cd cl("Beatles","Capitol",14,35,5);Classic c2 = Classic("piano Sonata in B flat,Fantasia in C""Alfred Brendel","Philips",2,57.17);
    Cd *pcd = &cl;
    cout // use Cd method
    c2.Report();
    //use Classic method
    cout << "Using type cd * pointer to objects:\n";pcd->Report();// use cd method for cd objectpcd = &c2;
    pcd->Report(); // use Classic method for classic object
    cout << "Calling a function with a Cd reference argument:\n";Bravo(c1);Bravo(c2];
    cout cc "Testing assignment: ";Classic copyi
    copy= c2;
    copy.Report()
    return 0;
    void Bravo(const Cd & disk)
    disk.Report();

    1. #include
    2. using namespace std;
    3. #include "classic.h"
    4. void Bravo(const Cd &disk);
    5. int main()
    6. {
    7. Cd c1("Beatles", "Capitol", 14, 35.5);
    8. Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C",
    9. "Alfred Brendel", "Philips", 2, 57.17);
    10. Cd *pcd = &c1;
    11. cout << "Using object directly:\n";
    12. c1.Report();
    13. c2.Report();
    14. cout << "Using type cd * pointer to objects:\n";
    15. pcd->Report();
    16. pcd = &c2;
    17. pcd->Report();
    18. cout << "Calling a function with a Cd reference argument:\n";
    19. Bravo(c1);
    20. Bravo(c2);
    21. cout << "Testing assignment:\n";
    22. Classic copy;
    23. copy = c2;
    24. copy.Report();
    25. return 0;
    26. }
    27. void Bravo(const Cd &disk)
    28. {
    29. disk.Report();
    30. }
    1. #ifndef CD_H_
    2. #define CD_H_
    3. class Cd
    4. {
    5. private:
    6. char performers[50];
    7. char labels[20];
    8. int selections;
    9. double playtime;
    10. public:
    11. Cd(const char *s1, const char *s2, int n, double x);
    12. Cd(const Cd &d);
    13. Cd();
    14. virtual ~Cd();
    15. virtual void Report() const;
    16. Cd &operator=(const Cd &d);
    17. };
    18. #endif
    1. #include
    2. #include "cd.h"
    3. #include
    4. Cd::Cd(const char *s1, const char *s2, int n, double x) //用户定义构造函数;
    5. {
    6. std::strncpy(performers, s1, 50);
    7. performers[49] = '\0';
    8. std::strncpy(labels, s2, 20);
    9. labels[19] = '\0';
    10. selections = n;
    11. playtime = x;
    12. }
    13. Cd::Cd(const Cd &d) //用户定义构造函数;
    14. {
    15. std::strncpy(performers, d.performers, 50);
    16. performers[49] = '\0';
    17. std::strncpy(labels, d.labels, 50);
    18. labels[49] = '\0';
    19. selections = d.selections;
    20. playtime = d.playtime;
    21. }
    22. Cd::Cd() //用户定义默认构造函数;
    23. {
    24. performers[0] = '\0';
    25. labels[0] = '\0';
    26. selections = 0;
    27. playtime = 0.0;
    28. }
    29. Cd::~Cd()
    30. {
    31. }
    32. void Cd::Report() const
    33. {
    34. std::cout << "Performers: " << performers << std::endl;
    35. std::cout << "Label: " << labels << std::endl;
    36. std::cout << "Selections: " << selections << std::endl;
    37. std::cout << "Playtime: " << playtime << std::endl;
    38. }
    39. Cd &Cd::operator=(const Cd &d)
    40. {
    41. if (this == &d)
    42. {
    43. return *this;
    44. }
    45. std::strncpy(performers, d.performers, 50);
    46. performers[49] = '\0';
    47. std::strncpy(labels, d.labels, 20);
    48. labels[19] = '\0';
    49. selections = d.selections;
    50. playtime = d.playtime;
    51. return *this;
    52. }
    1. #ifndef CLASSIC_H_
    2. #define CLASSIC_H_
    3. #include "cd.h"
    4. class Classic : public Cd
    5. {
    6. private:
    7. char cdstr[50];
    8. public:
    9. Classic() : Cd() { cdstr[0] = '\0'; }
    10. Classic(const char *s, const char *s1, const char *s2, int n, double x);
    11. Classic(const char *s, const Cd &d);
    12. ~Classic();
    13. virtual void Report() const;
    14. Classic &operator=(const Classic &cs);
    15. };
    16. #endif
    1. #include
    2. #include
    3. #include "classic.h"
    4. Classic::Classic(const char *s, const char *s1, const char *s2, int n, double x) : Cd(s1, s2, n, x)
    5. {
    6. std::strncpy(cdstr, s, 50);
    7. cdstr[49] = '\0';
    8. }
    9. Classic::Classic(const char *s, const Cd &d) : Cd(d)
    10. {
    11. std::strncpy(cdstr, s, 50);
    12. cdstr[49] = '\0';
    13. }
    14. Classic::~Classic()
    15. {
    16. }
    17. void Classic::Report() const
    18. {
    19. Cd::Report();
    20. std::cout << "Major article in the CD is: " << cdstr << std::endl;
    21. std::cout.put('\n');
    22. }
    23. Classic &Classic::operator=(const Classic &cs)
    24. {
    25. if (this == &cs)
    26. {
    27. return *this;
    28. }
    29. Cd::operator=(cs);
    30. std::strncpy(cdstr, cs.cdstr, 50);
    31. cdstr[49] = '\0';
    32. return *this;
    33. }

    2.完成练习 1,但让两个类使用动态内存分配而不是长度固定的数组来记录字符串。

    1. #include
    2. using namespace std;
    3. #include "classic.h"
    4. void Bravo(const Cd &disk);
    5. int main()
    6. {
    7. Cd c1("Beatles", "Capitol", 14, 35.5);
    8. Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C",
    9. "Alfred Brendel", "Philips", 2, 57.17);
    10. Cd *pcd = &c1;
    11. cout << "Using object directly:\n";
    12. c1.Report();
    13. c2.Report();
    14. cout << "Using type cd * pointer to objects:\n";
    15. pcd->Report();
    16. pcd = &c2;
    17. pcd->Report();
    18. cout << "Calling a function with a Cd reference argument:\n";
    19. Bravo(c1);
    20. Bravo(c2);
    21. cout << "Testing assignment:\n";
    22. Classic copy;
    23. copy = c2;
    24. copy.Report();
    25. return 0;
    26. }
    27. void Bravo(const Cd &disk)
    28. {
    29. disk.Report();
    30. }
    1. #ifndef CD_H_
    2. #define CD_H_
    3. class Cd //原有的数组修改为指针便于动态分配内存;
    4. {
    5. private:
    6. char *performers;
    7. char *labels;
    8. int selections;
    9. double playtime;
    10. public:
    11. Cd(const char *s1, const char *s2, int n, double x);
    12. Cd(const Cd &d);
    13. Cd();
    14. virtual ~Cd(); //虚析构函数;
    15. virtual void Report() const;
    16. Cd &operator=(const Cd &d);
    17. };
    18. #endif
    1. #include
    2. #include "cd.h"
    3. #include
    4. Cd::Cd(const char *s1, const char *s2, int n, double x) //用户定义构造函数;
    5. {
    6. performers = new char[std::strlen(s1) + 1];
    7. std::strcpy(performers, s1);
    8. labels = new char[std::strlen(s2) + 1];
    9. std::strcpy(labels, s2);
    10. selections = n;
    11. playtime = x;
    12. }
    13. Cd::Cd(const Cd &d) //用户定义构造函数;
    14. {
    15. performers = new char[std::strlen(d.performers) + 1];
    16. std::strcpy(performers, d.performers);
    17. labels = new char[std::strlen(d.labels) + 1];
    18. std::strcpy(labels, d.labels);
    19. selections = d.selections;
    20. playtime = d.playtime;
    21. }
    22. Cd::Cd() //用户定义默认构造函数;
    23. {
    24. performers = new char[1];
    25. performers[0] = '\0';
    26. labels = new char[1];
    27. labels[0] = '\0';
    28. selections = 0;
    29. playtime = 0.0;
    30. }
    31. Cd::~Cd()
    32. {
    33. delete[] performers;
    34. delete[] labels;
    35. }
    36. void Cd::Report() const
    37. {
    38. std::cout << "Performers: " << performers << std::endl;
    39. std::cout << "Label: " << labels << std::endl;
    40. std::cout << "Selections: " << selections << std::endl;
    41. std::cout << "Playtime: " << playtime << std::endl;
    42. }
    43. Cd &Cd::operator=(const Cd &d) //重载赋值运算符;
    44. {
    45. if (this == &d)
    46. {
    47. return *this;
    48. }
    49. delete[] performers; //释放原有已分配的内存空间;
    50. delete[] labels; //同上;
    51. performers = new char[std::strlen(d.performers) + 1];
    52. std::strcpy(performers, d.performers);
    53. labels = new char[std::strlen(d.labels) + 1];
    54. std::strcpy(labels, d.labels);
    55. selections = d.selections;
    56. playtime = d.playtime;
    57. return *this;
    58. }
    1. #ifndef CLASSIC_H_
    2. #define CLASSIC_H_
    3. #include "cd.h"
    4. class Classic : public Cd //公有继承派生类;
    5. {
    6. private:
    7. char *cdstr;
    8. public:
    9. Classic();
    10. Classic(const char *s1, const char *s2, const char *s3, int n, double x);
    11. Classic(const char *s, const Cd &d);
    12. ~Classic();
    13. virtual void Report() const;
    14. Classic &operator=(const Classic &cs);
    15. };
    16. #endif
    1. #include
    2. #include
    3. #include "classic.h"
    4. Classic::Classic() : Cd()
    5. {
    6. cdstr = new char[1];
    7. cdstr[0] = '\0';
    8. }
    9. Classic::Classic(const char *s, const char *s1, const char *s2, int n, double x) : Cd(s1, s2, n, x) //基类构造函数的成员列表初始化;
    10. {
    11. cdstr = new char[std::strlen(s) + 1];
    12. std::strcpy(cdstr, s);
    13. }
    14. Classic::Classic(const char *s, const Cd &d) : Cd(d) //基类构造函数的成员列表初始化;
    15. {
    16. cdstr = new char[std::strlen(s) + 1];
    17. std::strcpy(cdstr, s);
    18. }
    19. Classic::~Classic()
    20. {
    21. delete[] cdstr;
    22. }
    23. void Classic::Report() const
    24. {
    25. Cd::Report();
    26. std::cout << "Major article in the CD is: " << cdstr << std::endl;
    27. std::cout.put('\n');
    28. }
    29. Classic &Classic::operator=(const Classic &cs)
    30. {
    31. if (this == &cs)
    32. {
    33. return *this;
    34. }
    35. delete[] cdstr;
    36. Cd::operator=(cs);
    37. cdstr = new char[std::strlen(cs.cdstr) + 1];
    38. std::strcpy(cdstr, cs.cdstr);
    39. return *this;
    40. }

    3.修改baseDMA-lacksDMA-hasDMA类层次,让三个类都从一个ABC派生而来,然后使用与程序清单13.10 相似的程序对结果进行测试。也就是说,它应使用ABC 指针数组并让用户决定要创建的对象类型。在类定义中添加virtual View()方法以处理数据显示。

    1. #include
    2. #include "dma.h"
    3. const int LEN = 3;
    4. int main()
    5. {
    6. using std::cin;
    7. using std::cout;
    8. using std::endl;
    9. DMA *temp[LEN];
    10. char label[50];
    11. int rating;
    12. char color[40];
    13. char style[50];
    14. char kind;
    15. cout << "Here are the process for creating 3 objects" << endl; //参考书上程序清单13.10让用户进行选择;
    16. for (int i = 0; i < LEN; i++)
    17. {
    18. cout << "Enter 1 for baseDMA, 2 for lacksDMA or 3 for hasDMA: ";
    19. while (cin >> kind && (kind != '1' && kind != '2' && kind != '3'))
    20. {
    21. cin.clear();
    22. while (cin.get() != '\n')
    23. continue;
    24. cout << "Please enter 1, 2 or 3: ";
    25. }
    26. if (kind == '1')
    27. {
    28. cout << "Please enter the label: ";
    29. cin >> label; //推荐输入书中样例Portabelly;
    30. cout << "Please enter the rating: ";
    31. cin >> rating; //推荐输入书中样例8;
    32. temp[i] = new baseDMA(label, rating, "baseDMA");
    33. }
    34. else if (kind == '2')
    35. {
    36. cout << "Please enter the color: ";
    37. cin >> color; //推荐输入书中样例red;
    38. temp[i] = new lacksDMA(color, "lacksDMA");
    39. }
    40. else
    41. {
    42. cout << "Please enter the style: ";
    43. cin >> style; //推荐输入书中样例Mercator;
    44. temp[i] = new hasDMA(style, "hasDMA");
    45. }
    46. }
    47. cout << "\nThe results after creating 3 objects" << endl;
    48. for (int i = 0; i < LEN; i++)
    49. {
    50. temp[i]->View();
    51. }
    52. for (int i = 0; i < LEN; i++)
    53. {
    54. delete temp[i];
    55. }
    56. cout << "Done.\n";
    57. return 0;
    58. }
    1. #ifndef DMA_H_
    2. #define DMA_H_
    3. #include
    4. class DMA
    5. {
    6. private:
    7. char *classname; //基类成员设为一个char指针方便分配内存空间保存派生类的类名;
    8. protected:
    9. const char *show_classname() const { return classname; } //抽象基类DMA的View方法不进行定义因此使用protected让派生类可以访问基类数据;
    10. public:
    11. DMA(const char *cn = "null"); //声明基类DMA的默认构造函数;
    12. DMA(const DMA &rs); //声明基类DMA的复制构造函数;
    13. DMA &operator=(const DMA &rs); //声明为基类DMA重载赋值运算符;
    14. virtual ~DMA(); //声明基类DMA的虚析构函数;
    15. virtual void View() const = 0; //声明基类DMA的纯虚函数;
    16. };
    17. class baseDMA : public DMA
    18. {
    19. private:
    20. char *label;
    21. int rating;
    22. public:
    23. baseDMA(const char *l = "null", int r = 0, const char *cn = "null"); //声明派生类baseDMA的默认构造函数;
    24. baseDMA(const char *l, int r, const DMA &rs); //声明派生类baseDMA的用户定义构造函数;
    25. baseDMA(const baseDMA &rs); //声明派生类baseDMA的复制构造函数;
    26. ~baseDMA(); //声明派生类baseDMA的析构函数;
    27. baseDMA &operator=(const baseDMA &rs); //声明为派生类baseDMA重载赋值运算符;
    28. virtual void View() const; //声明为派生类baseDMA定义基类虚函数;
    29. };
    30. class lacksDMA : public DMA
    31. {
    32. private:
    33. enum { COL_LEN = 40 };
    34. char color[COL_LEN];
    35. public:
    36. lacksDMA(const char *c = "blank", const char *cn = "null"); //声明派生类lacksDMA的默认构造函数;
    37. lacksDMA(const char *c, const DMA &rs); //声明派生类lacksDMA的用户定义构造函数;
    38. lacksDMA(const lacksDMA &rs); //声明派生类lacksDMA的复制构造函数;
    39. ~lacksDMA(); //声明派生类lacksDMA的析构函数;
    40. lacksDMA &operator=(const lacksDMA &rs); //声明为派生类lacksDMA重载赋值运算符;
    41. virtual void View() const; //声明为派生类lacksDMA定义基类虚函数;
    42. };
    43. class hasDMA : public DMA
    44. {
    45. private:
    46. char *style;
    47. public:
    48. hasDMA(const char *s = "none", const char *cn = "null"); //声明派生类hasDMA的默认构造函数;
    49. hasDMA(const char *s, const DMA &rs); //声明派生类hasDMA的用户定义构造函数;
    50. hasDMA(const hasDMA &rs); //声明派生类hasDMA的复制构造函数;
    51. ~hasDMA(); //声明派生类hasDMA的析构函数;
    52. hasDMA &operator=(const hasDMA &rs); //声明为派生类hasDMA重载赋值运算符;
    53. virtual void View() const; //声明为派生类hasDMA定义基类虚函数;
    54. };
    55. #endif
    1. #include "dma.h"
    2. #include
    3. DMA::DMA(const char *cn) //定义基类DMA的默认构造函数;
    4. {
    5. classname = new char[std::strlen(cn) + 1];
    6. std::strcpy(classname, cn);
    7. }
    8. DMA::DMA(const DMA &rs) //定义基类DMA的复制构造函数;
    9. {
    10. classname = new char[std::strlen(rs.classname) + 1];
    11. std::strcpy(classname, rs.classname);
    12. }
    13. DMA &DMA::operator=(const DMA &rs) //为基类DMA重载赋值运算符;
    14. {
    15. if (this == &rs)
    16. {
    17. return *this;
    18. }
    19. delete[] classname; //先释放后分配;
    20. classname = new char[std::strlen(rs.classname) + 1];
    21. std::strcpy(classname, rs.classname);
    22. return *this;
    23. }
    24. DMA::~DMA() //定义基类DMA的析构函数;
    25. {
    26. delete[] classname;
    27. }
    28. baseDMA::baseDMA(const char *l, int r, const char *cn) : DMA(cn) //定义派生类baseDMA的默认构造函数;
    29. {
    30. label = new char[std::strlen(l) + 1];
    31. std::strcpy(label, l);
    32. rating = r;
    33. }
    34. baseDMA::baseDMA(const char *l, int r, const DMA &rs) : DMA(rs) //定义派生类baseDMA的用户定义构造函数;
    35. {
    36. label = new char[std::strlen(l) + 1];
    37. std::strcpy(label, l);
    38. rating = r;
    39. }
    40. baseDMA::baseDMA(const baseDMA &rs) : DMA(rs) //定义派生类baseDMA的复制构造函数;
    41. {
    42. label = new char[std::strlen(rs.label) + 1];
    43. std::strcpy(label, rs.label);
    44. rating = rs.rating;
    45. }
    46. baseDMA::~baseDMA() //定义派生类baseDMA的析构函数;
    47. {
    48. delete[] label;
    49. }
    50. baseDMA &baseDMA::operator=(const baseDMA &rs) //为派生类baseDMA重载赋值运算符;
    51. {
    52. if (this == &rs)
    53. {
    54. return *this;
    55. }
    56. delete[] label; //先释放后分配;
    57. DMA::operator=(rs); //调用基类DMA的赋值运算符方法初始化派生类baseDMA的基类数据成员;
    58. label = new char[std::strlen(rs.label) + 1];
    59. std::strcpy(label, rs.label);
    60. rating = rs.rating;
    61. return *this;
    62. }
    63. void baseDMA::View() const //为派生类baseDMA定义基类虚函数;
    64. {
    65. std::cout << "Classname: " << show_classname() << std::endl; //调用基类protected中的show_classname方法显示基类数据成员;
    66. std::cout << "Label: " << label << std::endl;
    67. std::cout << "Rating: " << rating << std::endl;
    68. }
    69. lacksDMA::lacksDMA(const char *c, const char *cn) : DMA(cn) //定义派生类lacksDMA的默认构造函数;
    70. {
    71. std::strncpy(color, c, COL_LEN - 1);
    72. color[COL_LEN - 1] = '\0';
    73. }
    74. lacksDMA::lacksDMA(const char *c, const DMA &rs) : DMA(rs) //定义派生类lacksDMA的用户定义构造函数;
    75. {
    76. std::strncpy(color, c, COL_LEN - 1);
    77. color[COL_LEN - 1] = '\0';
    78. }
    79. lacksDMA::lacksDMA(const lacksDMA &rs) : DMA(rs) //定义派生类lacksDMA的复制构造函数;
    80. {
    81. std::strncpy(color, rs.color, COL_LEN - 1);
    82. color[COL_LEN - 1] = '\0';
    83. }
    84. lacksDMA::~lacksDMA()
    85. {
    86. }
    87. lacksDMA &lacksDMA::operator=(const lacksDMA &rs) //为派生类lacksDMA重载赋值运算符;
    88. {
    89. if (this == &rs)
    90. {
    91. return *this;
    92. }
    93. DMA::operator=(rs); //调用基类DMA的赋值运算符方法初始化派生类lacksDMA的基类数据成员;
    94. std::strncpy(color, rs.color, COL_LEN - 1);
    95. color[COL_LEN - 1] = '\0';
    96. return *this;
    97. }
    98. void lacksDMA::View() const //为派生类lacksDMA定义基类虚函数;
    99. {
    100. std::cout << "Classname: " << show_classname() << std::endl; //调用基类protected中的show_classname方法显示基类数据成员;
    101. std::cout << "Color: " << color << std::endl;
    102. }
    103. hasDMA::hasDMA(const char *s, const char *cn) : DMA(cn) //定义派生类hasDMA的默认构造函数;
    104. {
    105. style = new char[std::strlen(s) + 1];
    106. std::strcpy(style, s);
    107. }
    108. hasDMA::hasDMA(const char *s, const DMA &rs) : DMA(rs) //定义派生类hasDMA的用户定义构造函数;
    109. {
    110. style = new char[std::strlen(s) + 1];
    111. std::strcpy(style, s);
    112. }
    113. hasDMA::hasDMA(const hasDMA &rs) : DMA(rs) //定义派生类hasDMA的复制构造函数;
    114. {
    115. style = new char[std::strlen(rs.style) + 1];
    116. std::strcpy(style, rs.style);
    117. }
    118. hasDMA::~hasDMA() //定义派生类hasDMA的析构函数;
    119. {
    120. delete[] style;
    121. }
    122. hasDMA &hasDMA::operator=(const hasDMA &rs) //为派生类hasDMA重载赋值运算符;
    123. {
    124. if (this == &rs)
    125. {
    126. return *this;
    127. }
    128. delete[] style; //先释放后分配;
    129. DMA::operator=(rs); //调用基类DMA的赋值运算符方法初始化派生类hasDMA的基类数据成员;
    130. style = new char[std::strlen(rs.style) + 1];
    131. std::strcpy(style, rs.style);
    132. return *this;
    133. }
    134. void hasDMA::View() const //为派生类hasDMA定义基类虚函数;
    135. {
    136. std::cout << "Classname: " << show_classname() << std::endl; //调用基类protected中的show_classname方法显示基类数据成员;
    137. std::cout << "Style: " << style << std::endl;
    138. }

    4.BenevolentOrderof Programmers用来维护瓶装葡萄酒箱。为描述它BPPortmaster设置了一个Port类,其声明如下:

    #include'
    using- namespace std;
    class Port
    private:
    char *brand;-charkstyle(201//ieawnyrubyintagesiintbottles;-public.飞+A
    Port(const char *br"none",~const char:*st   "none, int b  0)
    Port(const Port 5 p);
    copy constructor
    virtual.-Port(- delete ll brand;
    Port &~operator=(const.Port 5 p):.Port & operator+=(int b) ,
    Port 5 operator-=(int bj;available
    // addsb-tobottles// subtracts b from bottles, if
    --
    int'BottleCount() const-f return bottles;virtual void showl const:
    friend ostream & operatores(ostream & os,const Port & p);

    show()方法按下面的格式显示信息
    Brand:GalFo
    Kind: tawnyBottles:20
    operator<<()函数按下面的格式显示信息(末尾没有换行符):Gal1o,tawnyr20-
    PortMaster 完成了-Port类的方法定义后派生了VintagePort类然后被解职-因为不小心将一瓶45度Cockbum泼到了正在准备烤肉调料的人身上VintagePort类如下所示:

    class VintagePort :publicPort// style-necessarily=vintage
    -ai
    private:
    ehar.*.nickname;
    int year!
    public:
    VintagePortl:
    // 1.e,r ."TheNoble".or "oldvelvet",etc ..vintageyear
    VintagePort(const char* ,br;int b,const char *inn,int y);;+yintagePortqconstVintagePort-&vp)------_.-
    VintagePort(E-delete l] nicknamerVintageport 5 operator=(const VintagePort  vpF;void Show(yconst:....-..
    friend ostream  operator<<(ostream os,const Vintageport & vp);

    您被指定负责完成 VintagePorta
    a.第一个任务是重新创建Port 方法定义,因为前任被开除时销毁了方法定义

    b.第二个任务是解释为什么有的方法重新定义了,而有些没有重新定义。
    c.第三个任务是解释为何没有operator-)和operator<<()声明为虚的。
    d.第四个任务是提供VintagePort 中各个方法的定义。

    1. #include "port.h"
    2. #include "vintageport.h"
    3. int main()
    4. {
    5. Port wine1("Gallo", "tawny", 20); //构造Port基类对象;
    6. VintagePort wine2("Lafei", 10, "strong wine", 1876); //构造VintagePort基类对象;
    7. VintagePort wine3("Merlot", 50, "middle wine", 1976); //构造VintagePort基类对象;
    8. cout << "Here is the Port object:\n";
    9. wine1.Show(); //调用基类Show方法;
    10. cout << wine1 << endl; //调用基类重载输出流运算符;
    11. cout << "\nHere are the VintagePort objects:\n";
    12. wine2.Show(); //调用派生类Show方法;
    13. cout << wine2 << endl; //调用派生类重载输出流运算符;
    14. wine3.Show(); //调用派生类Show方法;
    15. cout << wine3 << endl; //调用派生类重载输出流运算符;
    16. cout << "\nGallo add 20 bottles:\n";
    17. wine1 += 20; //调用基类重载+=运算符;
    18. wine1.Show();
    19. cout << "\nLafei add 10 bottles:\n";
    20. wine2 += 10; //调用派生类重载+=运算符;
    21. wine2.Show();
    22. cout << "\nMerlot minus 10 bottles:\n";
    23. wine3 -= 10; //调用派生类重载-=运算符;
    24. wine3.Show();
    25. VintagePort wine4(wine2); //调用派生类复制构造函数;
    26. cout << "\nResult of VintagePort copy:\n";
    27. wine4.Show();
    28. VintagePort wine5;
    29. wine5 = wine3; //调用派生类重载赋值运算符;
    30. cout << "\nResult of VintagePort assignment:\n";
    31. wine5.Show();
    32. return 0;
    33. }
    1. #ifndef PORT_H_
    2. #define PORT_H_
    3. #include
    4. using namespace std;
    5. class Port
    6. {
    7. private:
    8. char *brand;
    9. char style[20];
    10. int bottles;
    11. public:
    12. Port(const char *br = "none", const char *st = "none", int b = 0);
    13. Port(const Port &p);
    14. virtual ~Port() { delete[] brand; };
    15. Port &operator=(const Port &p);
    16. Port &operator+=(int b);
    17. Port &operator-=(int b);
    18. int BottleCount() const { return bottles; }
    19. virtual void Show() const;
    20. friend ostream &operator<<(ostream &os, const Port &p);
    21. };
    22. #endif
    1. #include "port.h"
    2. #include
    3. Port::Port(const char *br, const char *st, int b)
    4. {
    5. brand = new char[std::strlen(br) + 1]; //new分配内存;
    6. std::strcpy(brand, br);
    7. std::strncpy(style, st, 20);
    8. style[19] = '\0'; //保证字符串是有效的;
    9. bottles = b;
    10. }
    11. Port::Port(const Port &p)
    12. {
    13. brand = new char[std::strlen(p.brand) + 1];
    14. std::strcpy(brand, p.brand);
    15. std::strncpy(style, p.style, 20);
    16. style[19] = '\0';
    17. bottles = p.bottles;
    18. }
    19. Port &Port::operator=(const Port &p)
    20. {
    21. if (this == &p)
    22. {
    23. return *this;
    24. }
    25. delete[] brand;
    26. brand = new char[std::strlen(p.brand) + 1];
    27. std::strcpy(brand, p.brand);
    28. std::strncpy(style, p.style, 20);
    29. style[19] = '\0';
    30. bottles = p.bottles;
    31. return *this;
    32. }
    33. Port &Port::operator+=(int b)
    34. {
    35. bottles += b;
    36. return *this; //返回调用对象的引用;
    37. }
    38. Port &Port::operator-=(int b)
    39. {
    40. bottles -= b;
    41. return *this; //返回调用对象的引用;
    42. }
    43. void Port::Show() const
    44. {
    45. cout << "Brand: " << brand << endl;
    46. cout << "Kind: " << style << endl;
    47. cout << "Bottles: " << bottles << endl;
    48. }
    49. ostream &operator<<(ostream &os, const Port &p)
    50. {
    51. os << p.brand << ", " << p.style << ", " << p.bottles;
    52. return os;
    53. }
    1. #ifndef VINTAGEPORT_H_
    2. #define VINTAGEPORT_H_
    3. class VintagePort : public Port
    4. {
    5. private:
    6. char *nickname;
    7. int year;
    8. public:
    9. VintagePort();
    10. VintagePort(const char *br, int b, const char *nn, int y);
    11. VintagePort(const VintagePort &vp);
    12. ~VintagePort() { delete[] nickname; }
    13. VintagePort &operator=(const VintagePort &vp);
    14. void Show() const;
    15. friend ostream &operator<<(ostream &os, const VintagePort &vp);
    16. };
    17. #endif
    1. #include
    2. #include "port.h"
    3. #include "vintageport.h"
    4. VintagePort::VintagePort() : Port("none", "vintage", 0) //成员列表初始化派生类的基类对象数据;
    5. {
    6. nickname = new char[1];
    7. nickname[0] = '\0';
    8. year = 0;
    9. }
    10. VintagePort::VintagePort(const char *br, int b, const char *nn, int y) : Port(br, "vintage", b) //成员列表初始化派生类的基类对象数据;
    11. {
    12. nickname = new char[std::strlen(nn) + 1];
    13. std::strcpy(nickname, nn);
    14. year = y;
    15. }
    16. VintagePort::VintagePort(const VintagePort &vp) : Port(vp) //调用基类复制构造函数初始化派生类的基类对象数据;
    17. {
    18. nickname = new char[std::strlen(vp.nickname) + 1];
    19. std::strcpy(nickname, vp.nickname);
    20. year = vp.year;
    21. }
    22. VintagePort &VintagePort::operator=(const VintagePort &vp)
    23. {
    24. if (this == &vp)
    25. {
    26. return *this;
    27. }
    28. delete[] nickname;
    29. Port::operator=(vp); //调用基类赋值运算符修改派生类的基类数据成员;
    30. nickname = new char[std::strlen(vp.nickname) + 1];
    31. std::strcpy(nickname, vp.nickname);
    32. year = vp.year;
    33. return *this;
    34. }
    35. void VintagePort::Show() const
    36. {
    37. Port::Show();
    38. cout << "Nickname: " << nickname << endl;
    39. cout << "Year: " << year << endl;
    40. }
    41. ostream &operator<<(ostream &os, const VintagePort &vp)
    42. {
    43. os << (const Port &)vp; //强制类型转换调用Port基类的重载输出流运算符方法;
    44. os << ", " << vp.nickname << ", " << vp.year;
    45. return os;
    46. }

  • 相关阅读:
    java计算机毕业设计会展中心招商服务平台MyBatis+系统+LW文档+源码+调试部署
    python毕业设计作品基于django框架 多用户商城平台系统毕设成品(7)中期检查报告
    手把手教你入门Python中的Web开发框架,干货满满!!
    redis数据库
    精准防疫有“利器”| 芯讯通助力数字哨兵护航复市
    聚观早报 | 苹果iOS 16正式版发布;任天堂直面会即将举办
    Spring Boot 开发环境热部署
    QT 状态机的使用
    Leetcode1732:找到最高海拔
    【spring cloud】(七)消息驱动——springcloud Stream
  • 原文地址:https://blog.csdn.net/sakura0908/article/details/132722528