C++ : adding an object to a set

2019-07-24 10:28发布

问题:

I am having trouble with adding an object to a set.

I use two classes in a header file, one for employees and a second one for managers. In the manager class I want to create a set of employees by adding employees who are subordinates for a particular manager. First I create a empty set for which I can add objects by calling a function.

It looks as follows:

header file

#ifndef EMPLOYEE_HH
#define EMPLOYEE_HH

#include <set>
#include <string>
#include <iostream>

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 ;
      }

    private:
      string _name ;
      double _salary ;

} ;

class Manager : public Employee {
    public:
      //Constructor
      Manager(const char* _name, double _salary):
         Employee(_name, _salary),
         _subordinates() {
      }

      // Accessors/Modifiers
      void addSubordinate(Employee& empl) {
         _subordinates.insert(empl) ;     // Error: no macthing function call for .insert()    
      }

    private:
      set<Employee*> _subordinates ;        

} ;

#endif  

Main script

#include <string>
#include <iostream>
#include "Employee.hh"

using namespace std ;

int main() {

    Employee emp = ("David", 10000) ;

    Manager mgr = ("Oscar", 20000) ;

    mgr.addSubordinate(emp);    

    return 0;

}

When compiling I get the error that no matching function can be called for _subordinates.insert(empl).

回答1:

The element's type of set is Employee*, but you're inserting Employee.

You might change _subordinates.insert(empl); to _subordinates.insert(&empl);.

(Changing the type of _subordinates from set<Employee*> to set<Employee> could fix the compiler error too, but it seems doesn't match the request.)

Note as @KenmanTsang pointed, using pointer got from stack variable might be dangerous. Consider about using smart pointer with new, such as std::set<std::unique_ptr<Employee>> _subordinates;.

BTW:

Employee emp = ("David", 10000) ;
Manager mgr = ("Oscar", 20000) ;

should be

Employee emp ("David", 10000) ;
Manager mgr ("Oscar", 20000) ;

or (since c++11)

Employee emp = {"David", 10000} ;
Manager mgr = {"Oscar", 20000} ;


回答2:

you can either fix by

a)

// Accessors/Modifiers
void addSubordinate(Employee& empl) {
    _subordinates.insert(new Employee(empl));
}

pros. Easy to fix the problem.

pros. No matter the caller object invalided or not. The copy you saved is safe

cons. You need to do your own memory management. delete all objects in ~Manager();

b)

private:
    set<Employee> _subordinates;

pros. No need to alter the functions

pros. Auto memory management done by compiler

cons. invoke too much copying with Employee class ( while insertion and retrieval case )