重载运算符<<在同一类中针对不同的成员变量两次



很抱歉以前有人问过这个问题,但我很难重载<<运算符以将不同的数据流式传输到多个文件中。

我有一个Player类,它具有以下属性:

char* name;
char* password;
int hScore;
int totalGames;
int totalScore;
int avgScore;

我想重载<<操作符两次:一次是将namepasswordhScore流式传输到"Players.txt"文件,另一次是根据每个玩家的名称将totalGamestotalScoreavgScore流式传输至不同的.txt文件,例如"Player1.txt"

以下是我的操作员在Player类中的样子:

friend ostream& operator<< (std::ostream& os, Player& player)
{
os << player.name << "n" << player.encryptPassword((player.password), 3) << "n" << player.hScore << "n";
return os;
}

这里是我对它的调用,来自一个PlayerLibrary类,它包含一个向量Players:

ofstream out("Yahtzee.txt");
if (out.is_open())
{
for_each(playerList.begin(), playerList.end(), [&out](Player* player) {out << (*player);});
}
else
{
cout << "THERE WAS AN ERROR WRITING TO FILEn";
}

基本上,我想将其他变量流式传输到另一个文件中,该文件以玩家名称命名,并包含他们玩过的每个游戏的记分卡。到目前为止,它看起来像:

for (auto it = playerList.begin(); it != playerList.end(); ++it)
{
auto position = it - playerList.begin();
string filename(playerList[position]->getName());
filename = filename + ".txt";
ofstream out2(filename);
for (int i = 0; i < playerList[position]->getNumberOfScorecards(); i++)
{
out2 << *playerList[position]->getScorecard(i);
}
}

这只会流式传输记分卡,而不是像我希望的那样流式传输totalGamestotalScoreavgScore

我试着把这些变量转移到记分卡类中,但我觉得把它们放在原地更有意义。

我知道,如果两个重载都有相同的参数,我不能重载operator<<两次,有其他方法吗?是否在重载函数中使用输出流并检查.txt文件的名称或其他内容。

希望这个问题有道理。

与其为Player本身定义operator<<,不如创建两个引用Player并具有自己的operator<<的实用程序类型,让它们决定要流式传输Player的哪些部分,例如:

class Player
{
private:
std::string name;
std::string password;
int hScore;
int totalGames;
int totalScore;
int avgScore;
...
public:
...
std::string getName{} const { return name; }
...
std::string EncryptPassword(int arg) const { return ...; }
int getNumberOfScorecards() const { return ...; }
Scorecard* getScorecard(int index) const { return ...; }
class Info
{
const Player &m_player;
void print(std::ostream &os) const {
os << m_player.name << "n" << m_player.encryptPassword(3) << "n" << m_player.hScore << "n";
}
public:
Info(const Player &player) : m_player(player) {}
friend std::ostream& operator<<(std::ostream &os, const Info &info)
{
info.print(os);
return os;
}
};
friend class Info;
struct Stats
{
const Player &m_player;
void print(std::ostream &os) const
{
os << m_player.totalGames << "n" << m_player.totalScore << "n" << m_player.avgScore << "n";
}
public:
Stats(const Player &player) : m_player(player) {}
friend std::ostream& operator<<(std::ostream &os, const Stats &stats)
{
stats.print(os);
return os;
}
};
friend class Stats;
};

然后你可以这样使用它们:

ofstream out("Yahtzee.txt");
if (out.is_open())
{
for(auto *player : playerList)
out << Player::Info(*player);
}
else
{
cout << "THERE WAS AN ERROR WRITING TO FILEn";
}
for (auto *player : playerList)
{
ofstream out2(player->getName() + ".txt");
out2 << Player::Stats(*player);
for (int i = 0; i < player->getNumberOfScorecards(); ++i)
{
out2 << *player->getScorecard(i);
}
}

在线演示

最新更新