alexis
alexis

Reputation: 31

C++ Inheritance of functions, passing in arguments

Base class : Employee
Derived class : Regular

Employee.cpp

void Employee::setValue(string id, string name, double s, int n)
{
    empID = id;
    empName = name;
    salary = s;
}

Regular.cpp

void Regular::setValue(string id, string name, double s, int n) 
{
    annualLeave = n;
}

Employee::setValue() only stores the first 3 arguments passed in, but not int n, too.

I'm supposed to inherit that setValue() in Regular::setValue() and then just pass in the arguments, but this time store int n to annualLeave.

How do I do that?

Or, is there a way for me to set int n in the base class for the child class?

Upvotes: 0

Views: 251

Answers (2)

bipll
bipll

Reputation: 11940

You can call the base class's implementation:

void Regular::setValue(string id, string name, double s, int n) {
    annualLeave = n;
    return Employee::setValue(std::move(id), std::move(name), s);
}

Otherwise, make base class polymorphic:

struct Employee {
    void setValue(string id, string name, double s, int n) {
        empID = std::move(id);
        empName = std::move(name);
        salary = s;
        setLeave(n);
    }
    virtual ~Employee() {}
protected:
    virtual void setLeave(int) = 0;
    string empID;
    string empName;
    double salary;
};

struct Regular: Employee {
private:
    void setLeave(int n) override { annualLeave = n; }
    int annualLeave;
};

Upvotes: 2

Amit G.
Amit G.

Reputation: 2674

If necessary to keep a single-signature setValue function, it is possible to do it like that:

-

Includes:

#include <any>
#include <map>
#include <string>

-

Employee.h:

class CEmployee
{
protected:
    virtual void setValue(std::map<std::string, std::any> &info);

    int m_empID = 0;
    std::string m_empName = {'\0'};
    int m_salary = 0;
}

Employee.cpp:

void CEmployee::setValue(std::map<std::string, std::any> &info)
{
    std::any item;

    item = info["empID"];
    if (item.has_value())
        m_empID = std::any_cast<int>(item); // int

    item = info["empName"];
    if (item.has_value())
        m_empName = std::any_cast<std::string>(item); // std::string 

    item = info["salary"];
    if (item.has_value())
        m_salary = std::any_cast<int>(item); // int 
}

-

Regular.h:

class CRegular : public CEmployee
{
public:
    void setValue(std::map<std::string, std::any> &info) override;

protected:
    std::string m_annualLeave = {'\0'};
}

Regular.cpp:

void CRegular::setValue(std::map<std::string, std::any> &info)
{
    std::any item;

    CEmployee::setValue(info);

    item = info["annualLeave"];
    if (item.has_value())
        m_annualLeave = std::any_cast<std::string>(item); // std::string 
}

-

& call it like that:

void MyClass::HardcodedExample()
{
    CRegular regular_employee;
    std::map<std::string, std::any> info, update;

    info["empID"] = { 100 };
    info["empName"] = { std::string("Trump") };
    info["salary"] = { 1000000 };
    info["annualLeave"] = { std::string("29 Jul 2018") };
    regular_employee.setValue(info); // Set all info

    // Or:
    update["annualLeave"] = { std::string("29 Dec 2018") };
    regular_employee.setValue(update); // Update just "annualLeave"

    // Or:
    update["salary"] = { 1200000 };
    update["annualLeave"] = { std::string("04 Jul 2018") };
    regular_employee.setValue(update); // Update "salary" & "annualLeave"
}

-

Otherwise, setValue with 3 parameters to base-class, & with 4 parameters to the derived-class (that calls to the base-class with the 3 parameters and sets by itself the 4th one) - similar to what @RemyLebeauis offers - is a better solution.

-

& better to use #define / enum keys instead of string-keys (& change the key-type of the map accordingly), but this is a different issue.

Upvotes: 0

Related Questions