今天又碰到这个问题,由于以前没有记笔记的习惯,所以碰到这个问题之后纠结了很久。友元函数本来就是给那些既需要访问类成员而又不能作为相关类的成员的函数或者类来访问类私有变量的方法。从这儿可以看出,友元函数会破坏类的封装性,所以还是少用为妙。
- #include "iostream"
- using namespace std;
- class MyClass
- {
- public:
- double val;
- MyClass(){a = b = 0;}
- MyClass(int x, int y)
- {
- a = x;
- b = y;
- val = 0.0;
- }
- ~MyClass()
- {
- cout << "Destructing MyClass(" << a << ", " << b << ")" << endl;
- }
- int sum()
- {
- return a + b;
- }
- friend ostream &operator<<(std::ostream &strm, const MyClass &obj);
- private:
- int a, b;
- };
- ostream &operator<<(ostream &strm, const MyClass &obj)//
- {
- strm << "(" << obj.a << " " << obj.b << ")";
- return strm;
- }
- int main(){
- return 0;
- }
- Compiling...
- test.cpp
- D:\VCProject\FriendTest\test.cpp(33) : error C2248: 'a' : cannot access private member declared in class 'MyClass'
- D:\VCProject\FriendTest\test.cpp(29) : see declaration of 'a'
- D:\VCProject\FriendTest\test.cpp(33) : error C2248: 'b' : cannot access private member declared in class 'MyClass'
- D:\VCProject\FriendTest\test.cpp(29) : see declaration of 'b'
于是,有两种方式可以解决这个问题:
方式一:注释掉 using namespace std;加上如下声明:
- using std::cout;
- using std::endl;
- using std::ostream;
- #include "iostream"
- //using namespace std;
- using std::cout;
- using std::endl;
- using std::ostream;
- class MyClass
- {
- public:
- double val;
- MyClass(){a = b = 0;}
- MyClass(int x, int y)
- {
- a = x;
- b = y;
- val = 0.0;
- }
- ~MyClass()
- {
- cout << "Destructing MyClass(" << a << ", " << b << ")" << endl;
- }
- int sum()
- {
- return a + b;
- }
- friend ostream &operator<<(std::ostream &strm, const MyClass &obj);
- private:
- int a, b;
- };
- ostream &operator<<(ostream &strm, const MyClass &obj)//
- {
- strm << "(" << obj.a << " " << obj.b << ")";
- return strm;
- }
- int main(){
- return 0;
- }
方法二:在程序中所以用的比如,ostream、istream、endl 等等std中的关键字前面都加上std::。比如:std::ostream,std::istream,std::endl;