Почему оператор "<<" может быть унаследован, но оператор ">>" не может?

83
12

Простите меня, если это просто глупый вопрос. Я все еще новичок в C++, и это моя практика. Я пытаюсь создать простую игру с объектом Actor Object и Enemy Object, который наследуется от Unit Object. Я поместил всю статистику и перегрузил оператора, чтобы Актер и Враг разделились в классе Unit. Здесь мой упрощенный код для каждого файла класса:

Примечание. Если этот код слишком длинный, просто прочитайте ошибку на Actor.cpp и пропустите все это. Я пишу все это, потому что я не знаю, где начинается моя ошибка.

Unit.h

#ifndef UNIT_H_INCLUDED
#define UNIT_H_INCLUDED

#include <iostream>
#include <fstream>
#include <string>

class Unit{

friend std::ostream& operator<<(std::ostream&, const Unit&);
friend std::istream& operator>>(std::istream&, Unit&);

public:
Unit(std::string name = "");

void setName(std::string);

std::string getName();

std::string getInfo();

int attack(Unit&);

protected:
std::string name;
};

#endif

Unit.cpp

#include "Unit.h"

using namespace std;

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

void Unit::setName(string name){
this->name = name;
}

string Unit::getName(){
return name;
}

string Unit::getInfo(){
string info;
info = "Name\t: " + name;
return info;
}

ostream& operator<<(ostream& output, const Unit& unit){

output << unit.name << "\n";

return output;
}
istream& operator>>(istream& input, Unit& unit){

input >> unit.name;

return input;
}

Actor.h

#ifndef ACTOR_H_INCLUDED
#define ACTOR_H_INCLUDED

#include "Unit.h"

class Actor: public Unit{
public:
void saveActor();
void loadActor();
};

#endif

Actor.cpp

#include "Actor.h"

using namespace std;

void Actor::saveActor(){
ofstream ofs("actor.txt");
if(ofs.is_open()){
ofs << this; // This work well.
}
ofs.close();
}
void Actor::loadActor(){
ifstream ifs("actor.txt");
if(ifs.is_open()){
ifs >> this; // This is the error.
}
ifs.close();
}

Этот код упрощен, мой настоящий код включает HP, MP, atk, def, mag, agi с наборами и получает для каждого поля, которое точно совпадает с полем имени. Вот почему мне нужно перегружать операторов "<<" и ">>".

Моя IDE (Visual Studio) сказала:

ошибка C2678: двоичный '>>': оператор не найден, который принимает левый операнд типа 'std :: istream' (или нет приемлемого преобразования)

Мой вопрос:

Почему класс Actor может наследовать перегруженный оператор вставки, но не может наследовать перегруженный оператор извлечения? Это хорошая идея включить эту стандартную библиотеку в мои заголовочные файлы или включить ее в файлы cpp?

Первый вопрос - моя проблема. Второй - это просто мое любопытство, мой опытный программист может дать мне совет.

Извините за мой плохой язык. Английский язык не является моим основным языком.

спросил(а) 2014-12-23T14:38:00+03:00 5 лет, 10 месяцев назад
1
Решение
121

Вы транслируете Actor*

ofs << this;
ifs >> this;

вместо потокового Actor:

ofs << *this;
ifs >> *this;

Строка ofs работает, потому что она вызывает перегрузку operator<< для указателей печати, а не потому, что вызывает перегрузку на Unit.

ответил(а) 2014-12-23T14:40:00+03:00 5 лет, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема