I'm c++新手,在<<操作符重载时遇到意外错误.你能给我一些建议吗?



在做一些代码练习时,我得到了一些错误

student.h文件

#pragma once
class Student {
public:
Student() = default;
Student(int id, const char* name, int score);
Student(const Student& s);

Student(Student&& other);
Student& operator=(Student&& other);
virtual ~Student();
**friend std::ostream & operator<<(std::ostream & os, const Student & rhs);**
void print();
private:
int mId;
char* mName;
int mScore;
size_t mSize;
};

student.cpp文件

#include "student.h"
#include <iostream>
#include <string>

... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; // Compile Error: Cannot Access Student Member(rhs.mId, rhs.mName...)

return os;
}

我得到的错误是我不能访问Student类成员,尽管我在Student .h中声明了它为友函数

奇怪的是,如果我像这样在student.cpp文件中声明#include<iostream>语句,它就编译成功了

#include <iostream>     //change position <iostream> and "student.h"
#include <string>
#include "student.h"

... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; //Compile successfully

return os;
}

那么,为什么#include语句序列很重要呢?我想#include语句只是复制粘贴到我的CPP文件。

并且当我将#include<iostream>声明到student.h,

时也编译成功。所以当我包含一些#include的东西最好的情况是声明它的头文件?

你能给我一些建议吗?

我在Visual Studio 2019中编译我的程序。

在student.h中添加iosfwd的include:

#pragma once
#include <iosfwd>
class Student ...

这将确保std::ostream符号的正确解析,并将您定义的ostream操作符识别为您声明为友元的操作符。

iosfwd头文件包含iostream头文件中符号的前向声明,它是为这个场景定义的。

在c++中,我们必须在使用任何东西之前声明它。

所以你的问题是你没有声明std::ostream,但你在student.h中使用了它。

一个合适的解是在student.h开头的#include <iostream>,#pragma once下面。

你也可以把这些放在class Stduent:

前面
namespace std
{
class ostream;
}

这叫做正向声明

相关内容

  • 没有找到相关文章

最新更新