子 classes 中的屏幕继承打印:来自 parent class 的 ostream 流

Inherited print on screen in subclasses: ostream flow from the parent class

对于不好的标题,我深表歉意,我是 self-taught c++ 新手。

我将编写公司 class 以及雇员 class 和个人 class 的常见示例。

基本上我的代码应该创建一个公司,向其添加员工并打印完整的员工列表。

这是我所做的简短版本。它看起来很长,但其实只有几行。其他的都很好,但我需要它们才能使代码正常工作。

// g++ test.cpp  -o exe.x && ./exe.x

#include <iostream>
#include <vector>


class Person {
    private:
        std::string name;
        std::string surname;

    public:
        Person() {};
        Person(const std::string n, const std::string m) : name(n), surname(m) {}
        ~Person() {};

    friend std::ostream & operator<<(std::ostream & os, const Person & person) {
        return os << person.name << " " << person.surname;
    }
};

class Employee: public Person {
    private:
        size_t salary;

    public:
        Employee(const Person p, const size_t w) {
            salary = w;
        }
        ~Employee() {};

    friend std::ostream & operator<<(std::ostream & os, const Employee & employee) {
        std::cout << employee;                                                  // this should call std::cout from Person
        return os << ", " << employee.salary;                                   // this should also print the salary as additional info
    }
};

class Company {

    private:
        std::string companyName;
        size_t maxNumberEmployees;
        std::vector<Employee> employees;

    public:
        Company(const std::string n, const size_t p) {
            companyName = n;
            maxNumberEmployees = p;
        }

        ~Company() {
            employees.clear();
        }

        void addEmployee(const Employee employee) {
            if (employees.size() < maxNumberEmployees) {
                employees.push_back(employee);
            }
            return;
        }

        void listEmployees() const {
            for (Employee employee : employees) {
                std::cout << employee << std::endl;
            }
            return;
        }
};


int main ( int argc, char* argv[] ) {

    Company com("CompanyName", 15);

    Person per("Name1", "Surname1");
    Employee imp(per, 2000);
    com.addEmployee(imp);

    com.listEmployees();

    return 0;
}

EmployeePerson 的 sub-class。在后者中,我定义了 std::cout 命令应该如何打印类型为 Person 的 object。

当我为 Employee object 提供 std::cout 时,我希望我的代码调用 Person class 的 std::cout , 在 Employee class.

中定义了附加信息

我在遇到这些问题的行中添加了两条评论。如果我这样 运行 代码就会卡住。 std::cout << employee 肯定有问题,就像它是递归函数一样。但我不知道如何按照我想要的方式解决它。

一般情况下,需要加一层间接。在Person中添加一个打印内容的虚函数:

virtual void print(std::ostream& os) {
    os << whatever;
}

并在 Employee 中覆盖它并调用基本版本:

void print(std::ostream& os) {
    Person::print(os);
    os << whatever;
}

最后,摆脱 Employee 的流插入器并为 Person 编写一个调用此函数的流插入器:

std::ostream& operator<<(std::ostream& os, const Person& person) {
    person.print(os);
    return os;
}

这是一个比您要求的更广泛的解决方案,但它更可靠。要按字面意思执行您要求的操作,只需使用 Person 子对象显式调用 << 运算符:

friend std::ostream & operator<<(std::ostream & os, const Employee & employee) {
    std::cout << static_cast<const Person&>(employee);
    return os << ", " << employee.salary;  
}