C ++ Наследование функций, передавая аргументы - PullRequest
0 голосов
/ 29 июня 2018

Базовый класс: Employee
Производный класс: 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() хранит только первые 3 переданных аргумента, но не int n тоже.

Я должен унаследовать это setValue() в Regular::setValue(), а затем просто передать аргументы, но на этот раз сохранить int n в annualLeave.

Как мне это сделать?

Или есть ли способ установить int n в базовом классе для дочернего класса?

Ответы [ 2 ]

0 голосов
/ 29 июня 2018

Если необходимо сохранить функцию setValue с единственной подписью , это можно сделать так:

-

Включает в себя:

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

-

и назовите это так:

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

-

В противном случае, setValue с 3 параметрами для базового класса и с 4 параметрами для производного класса (который вызывает базовый класс с 3 параметрами и устанавливает сам 4-й) - аналогично тому, что предлагает @RemyLebeauis - это лучшее решение.

-

и лучше использовать ключи #define / enum вместо строковых ключей (и соответственно изменить тип ключа карты), но это другая проблема.

0 голосов
/ 29 июня 2018

Вы можете вызвать реализацию базового класса:

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

В противном случае сделать базовый класс полиморфным:

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;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...