VC6.0中友元函数无法访问类私有成员的解决方法

VC6.0中友元函数无法访问类私有成员的解决办法
原文地址:

今天又碰到这个问题,由于以前没有记笔记的习惯,所以碰到这个问题之后纠结了很久。友元函数本来就是给那些既需要访问类成员而又不能作为相关类的成员的函数或者类来访问类私有变量的方法。从这儿可以看出,友元函数会破坏类的封装性,所以还是少用为妙。

#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;
}


方法二:在程序中不使用 namespace,把头文件替换为 .h , 如:
#include "iostream.h"
// using namespace std;


完整源代码如下:

#include "iostream.h"
//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;
}