Inheritance, struggeling with making my program more elegant

Hi, I'm making a code that prints out business cards for employees and managers. the header files looks like 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
#ifndef EMPLOYEE_HH
#define EMPLOYEE_HH

#include <string>
using namespace std ;

class Employee {

public:
  // Constructor
  Employee(const char* name, double salary) : _name(name), _salary(salary) {}

  // Accessors
  const char* name() const { return _name.c_str() ; }
  double salary() const { return _salary ; }


  // Print functions
  void businessCard(ostream& os = cout) const {
    os << "   +------------------+  " << endl
       << "   | ACME Corporation |  " << endl 
       << "   +------------------+  " << endl
       << "   " << name() << endl 
       << "   Salary:" << salary() << endl;
  }
  
private:

  string _name ;
  double _salary ;

} ;

#endif


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
#ifndef MANAGER_HH
#define MANAGER_HH
#include<string>
#include"employee.hh"
#include<set>
using namespace std;

class Manager : public Employee {
  
  public:
    
    Manager(const char* name, double salary) : Employee(name, salary) {}
  /* 
   const char* name() const{
    cout<< _name << " (Manager)"<< endl ;
   }*/
   
    //accesors and modifiers
    void addSubordinate(Employee& empl)
    {
      subordinates.insert(&empl);
    }
    
    const set<Employee*>& listOfSubordinates() const 
    {
      return subordinates ;
    }
    
    void businessCard( ostream& os = cout) const 
    {
      Employee::businessCard();
      
      set<Employee*>::iterator iter;
      iter = subordinates.begin();
      os <<"   Employees:"<< endl;
      
      while(iter != subordinates.end()) {
	if(subordinates.empty()){
	  os << "   None"<< endl;
	break;
	}
	else{
	  os << "   " << (*iter)->name() << endl;
	  iter++ ;
	}
      }
    }

  private:
    set<Employee*> subordinates ;
    

} ;

#endif


If I use the function businessCard(), it will create a businesscard for a employee or a manager, but on the manager's card there is also a list of his employees. I had the following in mind. Manager man1 has two employees: emp1 and emp2. Manager man3 has employees: man1 and man2 and of course the employees that belong to manager man1. So Manager man3 is on top of the pyramid, then man1 and man2 and at the bottom are emp1 and emp2. I wrote the following in my main:

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
#include<iostream>
#include"employee.hh"
#include"manager.hh"
using namespace std;

int main() {
  
  Employee emp1("A",500);
  Employee emp2("B",400);
  Manager man1("C", 5000);
  Manager man2("D",5000);
  Manager man3("Top",50000);
  
  man1.addSubordinate(emp1);
  man1.addSubordinate(emp2);
  
  man3.addSubordinate(man1);
  man3.addSubordinate(man2);
  
  man3.businessCard();


return 0;
}


When I print my card for Manager man3, I only get man1 and man2 on his card and not the employees emp1 and emp2. The easy way to solve it is to add extra code like, man3.addSubordinate(emp1); and the same for emp2. But I want to do it more elegantly, so if I use man3.addSubordinate(man1); then automatically emp1 and emp2 should be included in the set of subordinates of man3. I tried to figure out a piece of code in the manager.hh, but all attempts seemed fruitless and left me with a lot of frustration.

The last thing I tried was this code in manager.hh:
1
2
3
4
  void addSubordinate(Manager& mana){
    subordinates.insert(&mana);
    subordinates.insert(&mana.subordinates); 
   }


with the part &mana.subordinates I was trying to force the set of employees in mana into the other set subordinates. But it gives me a jungle of an error message (when you put it in manager.hh of course. Without it, my code just compiles properly)

1
2
3
4
5
 In file included from main.cc:3:
manager.hh: In member function β€˜void Manager::addSubordinate(Manager&)’:
manager.hh:20: error: no matching function for call to β€˜std::set<Employee*, std::less<Employee*>, std::allocator<Employee*> >::insert(std::set<Employee*, std::less<Employee*>, std::allocator<Employee*> >*)’
/usr/include/c++/4.4/bits/stl_set.h:408: note: candidates are: std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = Employee*, _Compare = std::less<Employee*>, _Alloc = std::allocator<Employee*>]
/usr/include/c++/4.4/bits/stl_set.h:435: note:                 typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator std::set<_Key, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, const _Key&) [with _Key = Employee*, _Compare = std::less<Employee*>, _Alloc = std::allocator<Employee*>]


Can anyone give me a bit of advice?
You need to add the subordinates one by one. There are a variety of ways to do it. I'll
use the simplest one (though it pains me a bit to write a loop).

1
2
3
typedef set<Employee*>::const_iterator Iter;
for( Iter i = mana.subordinates.begin(); i != mana.subordinates.end(); ++i )
    subordinates.insert( *i );


There are other ways to do it.

There are also probably other even more elegant designs, but they may go well beyond
your scope. (For example, by copying a manager A's set of employees to A's manager's
manager's set of employees, it makes it difficult to change a direct report of a manager,
since you must travel up the hierarchy and remove it from that's manager's manager's
list of reports, etc.)

Tnx jsmith.

My code compiles and does the thing I want. I also thought of the possibility to include a loop, but my brain was acting funny after a couple of hours looking at the code and finding a solution. I'll keep on practicing c++ until I can find the most elegant solution, so nothing will be beyond my scope anymore =)
Topic archived. No new replies allowed.