今天又碰到这个问题,由于以前没有记笔记的习惯,所以碰到这个问题之后纠结了很久。友元函数本来就是给那些既需要访问类成员而又不能作为相关类的成员的函数或者类来访问类私有变量的方法。从这儿可以看出,友元函数会破坏类的封装性,所以还是少用为妙。
#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;
}
当我在VC6.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'
上网一查,发现这是VC6.0的一个经典BUG,是VC6.0对友元函数的支持不够,同时跟namespace也有关系。
于是,有两种方式可以解决这个问题:
方式一:注释掉 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;