How to make overload operator << for person.cc?

I have constructed the person.cc and I have to appropriately overload operator<< so that I can print any type of person. The format to be used is: <person S surname N name [ T telephone]? [ E email]? The notation [a]? means that a may be present or absent.
My codes overloading the person by name and surname but I don't know how to overload it by telephone, email or both.
Can someone help me with this?


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
  #include <iostream>
#include <string>
#include <vector>

using namespace std;

class Person {
	string _name, _surname;
public:
	Person(){}
	Person(const string name, const string surname) : _name(name), _surname(surname){}

	string name() const {return _name;}
	string surname() const {return _surname;}

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

	bool hasTelephone() {return false;}
	bool hasEmail() {return false;}
};

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

	string telephone() const {return _telephone;} // Person's telephone

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

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

	string email() const {return _email;}

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

//Member publicly inherits with telephone and email
class PersonWithTelephoneAndEmail: public PersonWithTelephone, public PersonWithEmail {

public:

	PersonWithTelephoneAndEmail(const string name, const string surname, const string telephone, const string email) :
		Person(name, surname), PersonWithTelephone(telephone), PersonWithEmail(email) {}
};

/** Output stream overload */
ostream& operator << (ostream &out, const Person &p) {
	cout << "<" << "Person " << "S " << p.surname() << " N " << p.name() << ">" << endl;
	return out;
}

istream & readPerson(istream &in, Person * & p){return in;}

int main(){
	Person p1 ("Tom", "Smith");
	cout << p1 ;

	PersonWithTelephone p2 ("Dick", "Smith", "+49.921.1434");
	cout << p2;


	PersonWithEmail p3 ("Harry", "Smith", "hsmith@gmail.com");
	cout << p3;

	 PersonWithTelephoneAndEmail p4 ("Mary", "Smith", "+39.921.1434", "msmith@gmail.com");
	 cout << p4;

	 PersonWithTelephoneAndEmail p5 ("John", "John", "+33.921.1434", "jjohn@gmail.com");
	 cout << p5;
	return 0;
}
Overloading >> for the other person types is no different.
1
2
3
4
ostream& operator << (ostream &out, const PersonWithTelephone &p) 
{   cout << "<" << "Person " << "S " << p.surname() << " N " << p.name() << " T " << p.telephone() << ">" << endl;
	return out;
}


Seems like a lot of trouble, unless this is an exercise in inheritance.
Simply adding a string to Person for telephone and email, then checking if either is empty seems a whole lot easier.
1
2
3
4
5
6
7
8
9
10
/* 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 << ">" << endl;
    return out;
}
Thank you for your reply to my question. I added a string to Person for telephone and email but I got an error:

Multiple markers at this line
- 'std::__cxx11::string Person::_telephone' is
private
- 'std::__cxx11::string Person::_email' is
private

1
2
class Person {
	string _name, _surname, _telephone, _email;
The operator must be a friend of the Person class (see my note on line 1).

1
2
// After line 20 add:
friend ostream& operator << (ostream &out, const Person &p);

Topic archived. No new replies allowed.