Overload operator <<

I have constructed the person.cc but my overload operator << doesn't work correctly. The results which I received are:

<Person S Smith N Tom>
<Person S Smith N Dick>
<Person S Smith N Harry>
<Person S Smith N Mary>
<Person S John N John>

But I am looking for the following results:

<person S Smith N Tom >
<person S Smith N Dick T +49.921.1434 >
<person S Smith N Harry E hsmith@gmail.com >
<person S Smith N Mary T +39.921.1434 E msmith@gmail.com >
<person S John N John T +33.921.1434 E jjohn@gmail.com >

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  #include <iostream>
#include <string>
#include <vector>

using namespace std;

class person {
	string _name, _surname, _telephone, _email;
public:
	person(){}
	person(const string name, const string surname) : _name(name), _surname(surname){}

	//The name of the person
	string name() const {return _name;}
	//The surname of the person
	string surname() const {return _surname;}

	string get_name() const {return _name;} //Get name
	string get_surname() const {return _surname;} // Get surname

	bool has_telephone_p() {return false;}
	bool has_email_p() {return false;}

	friend ostream& operator << (ostream &out, const person &p);
};

// Class for person with telephone
class person_with_telephone: virtual public person {
	string _telephone;
public:
	person_with_telephone(){}
	person_with_telephone(string telephone) : person(), _telephone(telephone) {}
	person_with_telephone(const string name, const string surname, const string telephone) : person(name, surname), _telephone(telephone) {}

	//The telephone of the person
	string telephone() const {return _telephone;}

	string get_telephone() const {return _telephone;}
	void const set_telephone (string telephone) {_telephone = (telephone = 1 ? telephone : 0);}
};

//Class for person with email
class person_with_email: virtual public person {
	string _email;
public:
	person_with_email(){}
	person_with_email(string email) : person(), _email(email){}
	person_with_email(const string name, const string surname, const string email) : person(name, surname), _email(email) {}

	//The email of the person
	string email() const {return _email;}

	string get_email() const {return _email;}
	void const set_email (string email) {_email = (email = 1 ? email : 0);}
};

//Member publicly inherits with telephone and email
class person_with_telephone_and_email: public person_with_telephone, public person_with_email {
public:
	person_with_telephone_and_email(const string name, const string surname, const string telephone, const string email) :
		person(name, surname), person_with_telephone(telephone), person_with_email(email) {}
};

/* friend */
ostream& operator << (ostream &out, const person &p) {
	cout << "<" << "Person " << "S " << p.surname()<< " N " << p.name();
	if (!p._telephone.empty())
		cout << " T" << p._telephone;
	if (!p._email.empty())
		cout << " E " << p._email;
	cout << ">";
	return out;
}

istream & read_person(istream &in, person * & p){
	vector <person *> vpp;
	person *pp = 0;
	while (read_person(cin, pp) && pp)
		cout << *pp << endl;
	return in;
}

int main(){
    person p1 ("Tom", "Smith");
    person_with_telephone p2 ("Dick", "Smith", "+49.921.1434");
    person_with_email p3 ("Harry", "Smith", "hsmith@gmail.com");
    person_with_telephone_and_email p4 ("Mary", "Smith", "+39.921.1434", "msmith@gmail.com");
    person_with_telephone_and_email p5 ("John", "John", "+33.921.1434", "jjohn@gmail.com");

   vector <person *> vpp;
   vpp.push_back( &p1 );
   vpp.push_back( &p2 );
   vpp.push_back( &p3 );
   vpp.push_back( &p4 );
   vpp.push_back( &p5 );

   for (auto p : vpp)
	   cout << (*p) << endl;
   return 0;
}
Last edited on
This almost a duplicate of this post:

http://www.cplusplus.com/forum/beginner/179135/


If you have another question about the same code, just keep the original Topic going.
Variables are not virtual and do not override each other in any way: person::_telephone and person_with_telephone::_telephone are different objects within each person_with_telephone_and_email.

The constructor of person_with_telephone_and_email writes to person_with_telephone::_telephone and leaves person::_telephone empty. The operator<< reads from person::_telephone and has no idea the person is really person_with_telephone_and_email and has another _telephone exists in the hierarchy.

If you're studying OOP, you are probably expected to provide a virtual function in person, something like "virtual std::string person::to_string() const", which the derived class would override to append the derived members. Or perhaps those "has_telephone_p" are a clue.
Last edited on
Topic archived. No new replies allowed.