C ++如何从数组/基本元素集合中调用子操作符<<(ostream)

时间:2016-11-12 15:54:12

标签: c++ arrays ostream

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

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

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

这是当前的课程集合:

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);
}

Person.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;
}

Student.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);
};

Student.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;
}

Demo.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;
}

1 个答案:

答案 0 :(得分:3)

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

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

作为非成员函数,然后:

    virtual void print(std::ostream& str);
<{1>}中的

,并根据需要覆盖Base。 (Derived版本可以从Derived开始调用基本版本。)

您对Base::print(str);的声明没有问题,但您可以使用以下字符打印元素:

array

初始化数组的问题是,默认情况下,基类是私有的。修正:

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