0

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?

4
  • It doesn't look like the right place to use inheritance. Commented Jun 29, 2018 at 2:58
  • call Employee::setValue(id, name, salary);. And why does Employee take int n when it doesn't use it? Commented Jun 29, 2018 at 3:06
  • Why don't you add Employee::setValue(id, name, s, n); to Regular::setValue() ? Commented Jun 29, 2018 at 3:11
  • The easy way is for the derived method to invoke the base method. You did not mention which class is base, so, for example, with Regular the derived class, Regular::setValue() sets annualLeave, then invokes the Employee::setValue(), where the other 3 values are stored. Commented Jun 29, 2018 at 3:11

2 Answers 2

2

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;
};
Sign up to request clarification or add additional context in comments.

3 Comments

@RemyLebeau Excusez-moi?
You had issues in your code (you had a void method trying to return a value. And a pure virtual method that not all descendants may want to override, and a variable that didn't match the OP's code). So I fixed them for you, that's all. you are welcome.
Hmm? I. If you haven't noticed, my void method did not try to "return a value" it merely passed control to an (equally) void method. Returning a base class's implementation's result is a good illustration of how this redirection usually works, regardless void or not. II. Pure virtual method is again a demonstration of concept, if OP wanted it to have a default implementation, it wouldn't make trouble to add one. Moreover you've added an issue: it's polymorphic storing, not storage. So, once again, besides renaming a member variable—what was the purpose of your so vast edit?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.