Click here to Skip to main content
15,889,704 members
Please Sign up or sign in to vote.
1.50/5 (2 votes)
See more:
I have a base class "Employee" that has two child classes "Manager" and "Salesperson". In the Employee class I have a method called addSalesperon( Salesperson * ) and a vector member variable vector<Salesperson *> staff_list where it stores employee objects. addSalesperon( Salesperson * ) just pushes the salesperson into the vector. Each employee also has another vector vector<Insurance *> sale_list; that stores Class objects from a class I create called "Insurance".

I have a print method that loops through the Employee objects in staff_list vector and prints the the insurgence objects stored in sales_list vector at each index of staff_list. (Sorry I probably explained that poorly but if you look at the code you should be able to easily see what I was explaining)

The problem is when I try to call the print method nothing gets printed, but if I print the staff_list and sale_list vectors on their own they print fine. I'm just not sure whats wrong with my print method, and help clearing this up will be greatly appreciated!

Sample main:
C++
list<Insurance *> sales_list; // List of all sales made by any employee
vector<Employee *> employee_list; // List of all existing employees

Employee *m = new Manager("Bob", "Smith", 62000);
Employee *s1 = new Manager("Rick", "Smith", 45000);
Employee *s2 = new Manager("Dick", "Smith", 25000);
Insurance *a = new Auto("John", "Smith", "ford", "mustang", 123456789, 600, 796);
Insurance *b = new Home("Larry", "Smith", 45, 670, 3220, 4120);

    
m->addSalesperson(s1);
m->addSalesperson(s2);
s1->addSale(a);
s2->addSale(b);

employee_list.push_back(m);
employee_list.push_back(s1);
employee_list.push_back(s2);
sales_list.push_back(a);
sales_list.push_back(b);

printStaffSales::operator<<(cout, *m);


Employee class:
C++
class Employee{
protected:
    string first_name;
    string last_name;
    string employee_type;
    float base_salary;
    float commission;
    float total_salary;
    vector<Employee *> staff_list;
public:
    vector<Insurance *> sale_list; // holders pointers to the abstract Insurance class objects
    Employee():first_name(""), last_name(""), base_salary(0){ };
    Employee(string fn, string ln, float bs):first_name(fn), last_name(ln), base_salary(bs){ };

    void addSale( Insurance * );
    void addSalesperson( Employee * );

    virtual ostream &print_staff_sales( ostream & ) = 0;
    //Other methods left out
};

//2 other namespaces for different overloaded output operators not shown (they Work fine)
namespace printStaffSales {
    ostream &operator<<( ostream &, Employee & );
}

Employee.cpp

ostream &printStaffSales::operator<<( ostream &strm, Employee &e ){
    // Virtual print
    cout<< "Sales by employees under manager: " << endl;
    return e.print_staff_sales( strm );
}


Manager Class:
C++
class Manager: public Employee{
private:
    float staff_commission;
public:
    // Constructors
    Manager(): Employee(){ employee_type = "Manager"; };
    Manager(string fn, string ln, float bs): Employee(fn, ln, bs){ employee_type = "Manager";

    
    virtual ostream &print_staff_sales( ostream & );
    //Other methods left out
};


Print method
C++
ostream &Manager::print_staff_sales( ostream &strm ){
    strm << "Manager: " << first_name << " " << last_name << endl;
    
    Salesperson *s_temp;
    for (int i = 0; i < staff_list.size(); ++i){
        s_temp = staff_list.at(i);
        
        Insurance *i_temp;
        for (int i = 0; i < s_temp->sale_list.size(); ++i){
            i_temp = sale_list.at(i);
            strm<< *i_temp << endl;
        }
    }
    
    strm<< endl;
    return strm;
}
Posted
Updated 5-Aug-14 15:09pm
v8
Comments
CPallini 5-Aug-14 14:59pm    
It doesn't look the actual code, for instance e is NOT defined, in posted listing.
dombavetta 5-Aug-14 15:12pm    
You are correct, I created the question in a hurry and forgot to change those, it has been updated! Thanks for pointing that out
CPallini 5-Aug-14 15:51pm    
However this is just a part of the story. For instance, addSale and addSalesPerson method bodies are not shown.
dombavetta 5-Aug-14 16:17pm    
The definitions of both of those contain basically one line like so, sale_list.push_back(i); i being and insurance object (Employee object, if addSalesperson) So I didn't think it was necessary to include those! They both function correctly aswell.
CPallini 5-Aug-14 16:23pm    
Since there isn't an obvious failure in your code, I suppose we should see the actual one.

Change
C++
i_temp = sale_list.at(i);

to
C++
i_temp = s_temp->sale_list.at(i);
 
Share this answer
 
Comments
dombavetta 6-Aug-14 9:55am    
That was it, good catch! It's always the little things..
You missed the whole idea of OOP. This function exists in the object of the runtime type Manager, but you reference the object of this class with the compile-time type of the same object, where this function is not defined.

What to do? Many would advise using dynamic cast to the prospective runtime type. It would work in a pinch, but this would not be a solution at all, but the pure violation of the OOP. As you are not doing anything in OOP way, it would not be even an acceptable solution in a pinch, ad hoc. All kinds of down-casting would be such abuse.

To tell you want exactly to do, one would need to know all about your requirements. Essentially, you really need to redesign your code. For this purpose, you need to learn all of OOP, especially late binding and polymorphism, both based on virtual function. The main idea is to have a set of objects accessible by some compile-time type of the base type, accessing all the features of derived types through virtual dispatch mechanism.

There is plenty of literature on these topics and OOP in general. To start with, you need to understand it all really well.

—SA
 
Share this answer
 
Comments
dombavetta 5-Aug-14 15:11pm    
I actually was using a pure virtual function but failed to list it because I thought it was a problem inside the print_staff_sales method. I've updated the code in the question a little bit so you have a better look at what I was doing, so if you wouldn't mind taking a look again and maybe seeing if this changes anything for you.
Sergey Alexandrovich Kryukov 5-Aug-14 17:54pm    
Okay, in your new code addSalesPerson is defined in Employee, so what? Now you can call it, but the function is non-virtual, so you cannot have different implementations in different classes. Instead, you are checking up the type of the instance of a declaring class. It will work, but this is another kind of OOP abuse. Abuse as abuse... I tell you, you missed the whole idea. You need to learn how OOP works, especially the items I mentioned above.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900