C++ 如何从基本元素的数组/集合调用子运算符<<(ostream)

标签 c++ arrays ostream

假设我有一个带有字段字符串名称 的 Person 类。现在让我们有一个 Student 派生 Person 的类,它有一个字段 int avgGrade。这两个类都定义了运算符<<。

我希望能够将Person类型的元素存储在数组或类似结构中,而且能够在其中存储派生类对象。稍后我将遍历元素并希望使用运算符 << 并实际为该运算符调用该特定对象的定义,而不是始终调用它的基本版本。

我该怎么做?我应该在什么结构中存储什么类型的元素?

这是当前的类集合:

人.h:

#pragma once
#include <iostream>
class Person
{
private:
    std::string name;
public:
    Person();
    Person(std::string);

    friend std::ostream& operator<<(std::ostream& os, const Person& obj);
}

人.cpp:

#include "Person.h"

Person::Person() : Person("default") { }


Person::Person(std::string name)
{
    this->name = name;
}

std::ostream& operator<<(std::ostream& os, const Person& obj)
{
    os << "Name: " << obj.name;
    return os;
}

学生.h:

#pragma once
#include "Person.h"
#include <iostream>

class Student : Person
{
private:
    double avgGrade;
public:
    Student();
    Student(const std::string cs, const double avg_grade);

    friend std::ostream& operator<<(std::ostream& os, const Student& obj);
};

学生.cpp:

#include "Student.h"

Student::Student() : Student("default", 4) { }


Student::Student(const std::string cs, const double avg_grade)
    : Person(cs),
    avgGrade(avg_grade)
{
    this->avgGrade = avg_grade;
}

std::ostream& operator<<(std::ostream& os, const Student& obj)
{
    os << (Person)obj << std::endl;
    os << "Average grade: " << obj.avgGrade;
    return os;
}

演示.cpp:

#include "Person.h"
#include "Student.h"
#include <iostream>

int main(int argc, char* argv[])
{
    Person p("john");
    Student s("johana", 5);


    Person* arr[2];
    arr[0] = &p;
    arr[1] = &s; // Error: conversion to inaccessible base class "Person" is not allowed

    std::cout << arr[0] << std::endl;
    std::cout << arr[1] << std::endl;


    return 0;
}

最佳答案

解决这类问题的一般方法是声明:

inline std::ostream& operator<<(std::ostream& str, const Base& o)
{
    o.print(str);
    return str;
}

作为一个非成员函数,那么:

    virtual void print(std::ostream& str);

Base 中,并根据需要在 Derived 中覆盖。 (Derived 版本可能以 Base::print(str); 开头以调用基础版本。)

array 的声明没问题,但您随后会打印元素:

    std::cout << *arr[0] << std::endl;
    std::cout << *arr[1] << std::endl;

初始化数组的问题在于,默认情况下,基类是私有(private)的。解决这个问题:

class Student : public Person ...

关于C++ 如何从基本元素的数组/集合调用子运算符<<(ostream),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40564650/

相关文章:

c++ - 这段代码是一个有效的临界区包装类吗

c++ - 将 const char 转换为 char 时出现未处理的异常

c - 需要从数据文件中读取一个字符数组,我有一个循环设置,它只输出数字而不是我期望的字符

arrays - 字符串数组作为哈希函数键?

c++ - 错误 : cannot bind ‘std::basic_ostream’ lvalue to ‘std::basic_ostream&&’ sl << ss;

c++ - 如何使用 "ostream"指定小数位数

c++ - Thrust/CUDA reduce_by_key 给出不确定的结果

c++ - 如何迭代字符串的单词?

javascript - 如何在 Javascript 中基于另一个数组获取多个数组值