Documente Academic
Documente Profesional
Documente Cultură
char performers[50];
char label[20];
10
11 public:
12
13
14
Cd();
15
virtual ~Cd() {} ;
16
17
18 };
19
20 #endif
cd.cpp
1
#include <iostream>
#include "cd.h"
3
4
std::strncpy(performers,s1,49);
performers[49] = '\0';
std::strncpy(label,s2,19);
label[19] = '\0';
10
selections = n;
11
playtime = x;
12 }
13
14 Cd::Cd()
15 {
16
performers[0] = '\0';
17
label[0] = '\0';
18
selections = 0;
19
playtime = 0;
20 }
21
22 void Cd::Report() const
23 {
24
25
26
27
28 }
classic.h
1
#ifndef CLASSIC_H_
#define CLASSIC_H_
3
4
#include "cd.h"
5
6
private:
char primarywork[60];
10 public:
11
12
Classic();
13
~Classic() {};
14
15 };
16
17 #endif
classic.cpp
1 #include "classic.h"
2 #include <iostream>
3
4
5 Classic::Classic(char *pr, char *s1, char *s2, int n, double x) : Cd(s1,s2,n,x)
6 {
7
std::strncpy(primarywork,pr,59);
primarywork[59] = '\0';
9 }
10
11 Classic::Classic() : Cd()
12 {
13
primarywork[0] = '\0';
14 }
15
16 void Classic::Report() const
17 {
18
19
Cd::Report();
20 }
cp13ex1.cpp
1 #include <iostream>
2 #include "classic.h" // which will contain #include cd.h
3
4 using namespace std;
5 void Bravo(const Cd & disk);
6
7 int main()
8 {
9
1
Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C","Alfred Brendel",
0 "Philips", 2, 57.17);
1
1
1
2
1
3
Cd *pcd = &c1;
cout << "\nUsing object directly:\n";
c1.Report(); // use Cd method
c2.Report(); // use Classic method
cout << "\nUsing type cd * pointer to objects:\n";
1
4
1
5
pcd = &c2;
1
6
1
7
Bravo(c2);
1
8
Classic copy;
1
9
Bravo(c1);
copy = c2;
copy.Report();
2
0
2
1
2
2
std::cin.get();
std::cin.get();
return 0;
}
2
3 void Bravo(const Cd & disk)
2 {
4
disk.Report();
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
#ifndef CD2_H_
#define CD2_H_
3
4
// base class
private:
char * performers;
char * label;
10
11 public:
12
13
14
Cd();
15
virtual ~Cd();
16
17
18 };
19
20 #endif
cd2.cpp
1
#include <iostream>
#include "cd2.h"
3
4
std::strcpy(performers,s1);
std::strcpy(label,s2);
10
selections = n;
11
playtime = x;
12 }
13
14 Cd::Cd()
15 {
16
performers = NULL;
17
label = NULL;
18
selections = 0;
19
playtime = 0;
20 }
21
22 Cd::Cd(const Cd & d)
23 {
24
25
std::strcpy(performers,d.performers);
26
27
std::strcpy(label,d.label);
28
selections = d.selections;
29
playtime = d.playtime;
30 }
31
32 Cd & Cd::operator=(const Cd & d)
33 {
34
if (this == &d)
35
return *this;
36
delete [] performers;
37
delete [] label;
38
39
std::strcpy(performers,d.performers);
40
41
std::strcpy(label,d.label);
42
selections = d.selections;
43
playtime = d.playtime;
44
return *this;
45 }
46
47 void Cd::Report() const
48 {
49
50
51
52
53 }
54
55 Cd::~Cd()
56 {
57
delete [] performers;
58
delete [] label;
59 }
classic2.h
1
#ifndef CLASSIC2_H_
#define CLASSIC2_H_
3
4
#include "cd2.h"
5
6
private:
char * primarywork;
10 public:
11
12
Classic();
13
14
15
16
17 };
18
19 #endif
classic2.cpp
1 #include "classic2.h"
2 #include <iostream>
3
4
std::strcpy(primarywork,pr);
9 }
10
11 Classic::Classic() : Cd()
12 {
13
primarywork = NULL;
14 }
15
16 Classic::Classic(const Classic & d) : Cd(d)
17 {
18
19
std::strcpy(primarywork,d.primarywork);
20 }
21
22 Classic & Classic::operator =(const Classic &d)
23 {
24
if (this == &d)
25
return *this;
26
Cd::operator=(d);
27
delete [] primarywork;
28
29
std::strcpy(primarywork,d.primarywork);
30
return *this;
31 }
32
33 void Classic::Report() const
34 {
35
36
Cd::Report();
37}
cp13ex2.cpp
1 #include <iostream>
2 #include "classic2.h" // which will contain #include cd.h
3
4 using namespace std;
5 void Bravo(const Cd & disk);
6
7 int main()
8 {
9
1
Classic c2 = Classic("Piano Sonata in B flat, Fantasia in C","Alfred Brendel",
0 "Philips", 2, 57.17);
1
1
1
2
1
3
Cd *pcd = &c1;
cout << "\nUsing object directly:\n";
c1.Report(); // use Cd method
c2.Report(); // use Classic method
cout << "\nUsing type cd * pointer to objects:\n";
1
4
1
5
pcd = &c2;
1
6
1
7
Bravo(c2);
1
8
Classic copy;
1
9
Bravo(c1);
copy = c2;
copy.Report();
2
0
2
1
2
2
std::cin.get();
std::cin.get();
return 0;
2
3
2
4
2
5
2
6
2
7 }
2 void Bravo(const Cd & disk)
8
{
2
disk.Report();
9
3 }
0
3
1
3
2
3
3
3
4
4 #include <iostream>
5
6 class ABC_DMA
7{
8 private:
9
char * label;
1
0
int rating;
public:
1
1
1
2
virtual ~ABC_DMA();
1
3
1
4
1
5 };
1
6
1
9
2
0
2
1
};
2
2
char color[COL_LEN];
2 public:
6
lacksDMA(const char * c = "blank", const char * l = "null", int r = 0);
2
lacksDMA(const char * c, const ABC_DMA & rs);
7
void View() const;
2
8 };
2
9
3
0 class hasDMA : public ABC_DMA
3{
1 private:
3
2
3
3
3
4
3
5
3
6
char * style;
public:
hasDMA(const char * s = "none", const char * l = "null", int r = 0);
hasDMA(const char * s, const ABC_DMA & rs);
hasDMA(const hasDMA & hs);
~hasDMA(); // own special destructor is needed for DMA item style
hasDMA & operator=(const hasDMA & rs);
void View() const;
3 };
7
#endif
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
dma.cpp
1 // dma.cpp --dma class methods
2 #include "dma.h"
3 #include <cstring>
4
5 ABC_DMA::ABC_DMA(const char *l, int r)
6 {
7
std::strcpy(label,l);
rating = r;
10 }
11
12 ABC_DMA::ABC_DMA(const ABC_DMA & rs)
13 {
14
15
std::strcpy(label, rs.label);
16
rating = rs.rating;
17 }
18
19 ABC_DMA::~ABC_DMA()
20 {
21
delete [] label;
22 }
23
24 ABC_DMA & ABC_DMA::operator=(const ABC_DMA & rs)
25 {
26
if (this == &rs)
27
return *this;
28
delete [] label;
29
30
std::strcpy(label, rs.label);
31
rating = rs.rating;
32
return *this;
33 }
34
35 std::ostream & operator<<(std::ostream & os, const ABC_DMA & rs)
36 {
37
rs.View();
38
return os;
39 }
40
41 void ABC_DMA::View() const
42 {
43
44
45 }
46
47 baseDMA::baseDMA(const char * l, int r) : ABC_DMA(l,r)
48 {
49
50 }
51
52 // lacksDMA methods
53 lacksDMA::lacksDMA(const char * c, const char * l, int r) : ABC_DMA(l, r)
54 {
55
std::strncpy(color, c, 39);
56
color[39] = '\0';
57 }
58 lacksDMA::lacksDMA(const char * c, const ABC_DMA & rs) : ABC_DMA(rs)
59 {
60
std::strncpy(color, c, 39);
61
color[39] = '\0';
62 }
63
64 void lacksDMA::View() const
65 {
66
ABC_DMA::View();
67
68 }
69
70 // hasDMA methods
71 hasDMA::hasDMA(const char * s, const char * l, int r) : ABC_DMA(l, r)
72 {
73
74
std::strcpy(style, s);
75 }
76 hasDMA::hasDMA(const char * s, const ABC_DMA & rs) : ABC_DMA(rs)
77 {
78
79
std::strcpy(style, s);
80
81
82
86
std::strcpy(style, hs.style);
87 }
88 hasDMA::~hasDMA()
89 {
delete [] style;
90
91 }
94
return *this;
95
96
97
delete [] style;
98
99
std::strcpy(style, hs.style);
10
0
return *this;
}
10
void hasDMA::View() const
1
{
10
2
ABC_DMA::View();
10
3
10
4
cp13ex3.cpp
1 #include <iostream>
2 #include "dma.h"
3
4 const int LEN = 40; // max lenght of Label, Rating, Color, and Style strings
5 const int ITEMS = 4; // total of 4 items to be entered
6
7 int main()
8{
9
1
0
1
1
1
2
1
3
1
4
1
5
while ((cin >> choice).get() && (choice != '1' && choice != '2' && choice !
1 = '3')) // make sure choice is correct
6
{
1
7
1
8
cout << "\nItem #" << i + 1 << " Label: "; // Label and Rating are for all
1
three
classes
9
2
0
2
1
2
2
2
3
cin.getline(templabel,LEN);
cout << "Item #" << i + 1 << " Rating: ";
(cin >> temprating).get();
switch(choice)
{
2
5
case '2': cout << "Item #" << i + 1 << " Color: "; // if Balloon is
2 chosen, lacksDMA class
6
cin.getline(tempcolor,LEN);
2
pt[i] = new lacksDMA(tempcolor, templabel, temprating);
7
break;
2
8
2
case '3': cout << "Item #" << i + 1 << " Style: "; // if Map is chosen,
9 hasDMA class
3
0
cin.getline(tempstyle,LEN);
3
1
break;
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
2}
4
3
4
std::cin.get();
std::cin.get();
return 0;
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6
0
{
private:
char * brand;
char style[20]; // i.e., tawny, ruby, vintage
int bottles;
public:
Port(const char * br = none, const char * st = none, int b = 0);
Port(const Port & p); // copy constructor
virtual ~Port() { delete [] brand; }
Port & operator=(const Port & p);
Port & operator+=(int b); // adds b to bottles
Port & operator-=(int b); // subtracts b from bottles, if
available
int BottleCount() const { return bottles; }
virtual void Show() const;
friend ostream & operator<<(ostream & os, const Port & p);
};
The Show() method presents information in the following format:
Brand: Gallo
Kind: tawny
Bottles: 20
The operator<<() function presents information in the following format (with no
newline
character at the end):
Gallo, tawny, 20
The Portmaster completed the method definitions for the Port class and then
derived
the VintagePort class as follows before being relieved of his position for
accidentally
routing a bottle of 45 Cockburn to someone preparing an experimental barbecue
sauce:
class VintagePort : public Port // style necessarily = vintage
{
private:
char * nickname; // i.e., The Noble or Old Velvet, etc.
int year; // vintage year
public:
VintagePort();
VintagePort(const char * br, int b, const char * nn, int y);
VintagePort(const VintagePort & vp);
~VintagePort() { delete [] nickname; }
VintagePort & operator=(const VintagePort & vp);
void Show() const;
friend ostream & operator<<(ostream & os, const VintagePort & vp);
};
You get the job of completing the VintagePort work.
a. Your first task is to re-create the Port method definitions because the former
Portmaster immolated his upon being relieved.
b. Your second task is to explain why certain methods are redefined and others
are not.
c. Your third task is to explain why operator=() and operator<<() are not virtual.
d. Your fourth task is to provide definitions for the VintagePort methods.
My Answer:
Note: One way to do this exercise is to place style member into
protected section, this way it can be modified and set to vintage by
VintagePort class methods in all cases of copying or in any advanced
uses of this class. However, since this is an exercise for beginners
book, I find it unnecessary to complicate the code in this case, so style
is left unmodified in private section of Port class
port.h
1 #ifndef PORT_H_
2 #define PORT_H_
3
4 #include <iostream>
5
6 using namespace std;
7 class Port
8 {
9 private:
10
char * brand;
11
int bottles;
12
13 public:
14
15
16
17
18
19
20
21
22
friend std::ostream & operator<<(std::ostream & os, const Port & p);
23 };
24
25 #endif
port.cpp
1 #include "port.h"
2
3 Port::Port(const char * br, const char * st, int b)
4 {
5
std::strcpy(brand,br);
std::strncpy(style,st,19);
style[19] = '\0';
bottles = b;
10 }
11
12 Port::Port(const Port & p)
13 {
14
15
std::strcpy(brand,p.brand);
16
std::strncpy(style,p.style,19);
17
style[19] = '\0';
18
bottles = p.bottles;
19 }
20
21 Port & Port::operator=(const Port & p)
22 {
23
if (this == &p)
24
return *this;
25
delete [] brand;
26
27
std::strcpy(brand,p.brand);
28
std::strncpy(style,p.style,19);
29
style[19] = '\0';
30
bottles = p.bottles;
31
return *this;
32 }
33
34 Port & Port::operator+=(int b)
35 {
36
bottles += b;
37
return *this;
38 }
39
40 Port & Port::operator-=(int b)
41 {
42
bottles -= b;
43
return *this;
44 }
45
46 void Port::Show() const
47 {
48
49
50
51 }
52
53 std::ostream & operator<<(std::ostream & os, const Port & p)
54 {
55
os << p.brand << ", " << p.style << ", " << p.bottles;
56
return os;
57 }
vintage.h
1#ifndef VINTAGE_H_
2#define VINTAGE_H_
3
4#include "port.h"
5
6class VintagePort : public Port // style necessarily = vintage
7{
8private:
9 char * nickname; // i.e., The Noble or Old Velvet, etc.
1 int year; // vintage xxvcfyear
0
public:
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
VintagePort();
VintagePort(const char * br, int b, const char * nn, int y);
VintagePort(const VintagePort & vp);
~VintagePort() { delete [] nickname; }
VintagePort & operator=(const VintagePort & vp);
void Show() const;
friend ostream & operator<<(ostream & os, const VintagePort & vp);
};
#endif
vintage.cpp
1 #include "vintage.h"
2
3 VintagePort::VintagePort() : Port("none","vintage",0)
4 {
5
std::strcpy(nickname,"nonick");
year = 0;
8 }
9
1 VintagePort::VintagePort(const char * br, int b, const char * nn, int y) :
0 Port(br,"vintage",b)
1 {
1
1
2
1
3 }
year = y;
1
4
1
7
year = vp.year;
1
8
std::strcpy(nickname,vp.nickname);
delete [] nickname;
nickname = new char [std::strlen(vp.nickname)+1];
std::strcpy(nickname,vp.nickname);
year = vp.year;
return *this;
2 }
5
2
6 void VintagePort::Show() const
2 {
7
std::cout << "\nNickname: " << nickname;
2
8
2
9
Port::Show();
}
3
0
std::ostream & operator<<(ostream & os, const VintagePort & vp)
3
1 {
3
2
os << vp.nickname << ", " << vp.year << ", ";
3
3
return os;
3 }
4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
cp13ex4.cpp
1 #include <iostream>
2 #include "port.h"
3 #include "vintage.h"
4
5 int main()
6 {
7
8
9
Port sample1;
1
0
Port sample2("Kings","Bright",30);
1
1
1
2
Port sample3("NewOne","DarkRed",15);
VintagePort sample4("Valley",10,"Family",1957);
Port sample5(sample4);
1
3
sample4 += 10;
1
4
sample1 = sample5;
1
5
1
6
1
7
sample3 -= 5;
1
8
pts[i]->Show();
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
3
cin.get();
cout << "Sample #" << i + 1 << ": " << pts[i]->BottleCount() << "
3 bottles " << endl;
2
3
4
3 }
5
3
6
3
7
3
8
3
9
4
0
4
1
cin.get();
return 0;
b) Methods that werent redefined deal with non-dynamic data of base class and
could be automatically applied to any newly derived class without additional
operations or instructions to make the compatible with derived class. Such
methods include: operator+=(int b), Port & operator-=(int b), int BottleCount().
In these methods none of the dynamically allocated variables are used,
therefore, these methods could be applied to derived classes with no additional
instructions.
Methods were redefined that deal with dynamically allocated data or class
constructors that cant be inherited, or redefined copy constructors to
accommodate instructions for new dynamic data members such as nickname.
c) Assignment operator ( operator =() ) is not inherited, and it will have to be
redefined to accommodate for new nickname member which is dynamically
allocated. Operator<<() is not virtual because it is used as part of a friend
function, and since friend function is not a member of a class, it cannot be used
as virtual to invoke it by use of pointer-to-base class pointers, in other words,
dynamic binding cannot be used since it closely works with inherited methods,
not friendly non-class-member functions.