vc++6.0的一个BUG/// |
] |
前不久我在试验一个程序的时候,我把书上的程序完完全全的抄到编译器上(VC++ 6.0),运行说出错.是关于定义输入输出流操作符重载为友元的问题,现总结如下,供遇到这种情况的人一点参考:
程序是这样的:
#i nclude<iostream> #i nclude<iomanip> using namespace std; class Date{ int year, month, day; public: Date(int y=2000, int m=1, int d=1); // 设置默认参数 Date(const string& s); // 重载 bool isLeapYear()const; friend ostream& operator<<(ostream& o, const Date& h); }; Date::Date(const string& s){ year = atoi(s.substr(0,4).c_str()); month = atoi(s.substr(5,2).c_str()); day = atoi(s.substr(8,2).c_str()); } Date::Date(int y, int m, int d){ year=y,month=m,day=d; } bool Date::isLeapYear()const{ return (year % 4==0 && year % 100 )|| year % 400==0; } ostream& operator<<(ostream& o, const Date& h) { o<<setfill('0')<<setw(4)<<h.year<<'-'<<setw(2)<<h.month<<'-' <<setw(2)<<h.day<<'/n'<<setfill(' '); return o; } int main(){ Date c("2005-12-28"); Date d(2003,12,6); Date e(2002); // 默认两个参数 Date f(2002,12); // 默认一个参数 Date g; // 默认三个参数 cout<<c<<d<<e<<f<<g; return 0; } 错误是: --------------------Configuration: sadf - Win32 Debug-------------------- Compiling... sadf.cpp F:/学习资料/编程/vc++/cpp文件/sadf.cpp(32) : error C2248: 'year' : cannot access private member declared in class 'Date' F:/学习资料/编程/vc++/cpp文件/sadf.cpp(10) : see declaration of 'year' F:/学习资料/编程/vc++/cpp文件/sadf.cpp(32) : error C2248: 'month' : cannot access private member declared in class 'Date' F:/学习资料/编程/vc++/cpp文件/sadf.cpp(10) : see declaration of 'month' F:/学习资料/编程/vc++/cpp文件/sadf.cpp(33) : error C2248: 'day' : cannot access private member declared in class 'Date' F:/学习资料/编程/vc++/cpp文件/sadf.cpp(10) : see declaration of 'day' F:/学习资料/编程/vc++/cpp文件/sadf.cpp(42) : error C2593: 'operator <<' is ambiguous Error executing cl.exe.
sadf.obj - 4 error(s), 0 warning(s)
刚开始看到这些错误觉得简直是莫名其妙,问了很多人后终于明白了,
原来VC++ 6.0对友函数是有规定的,我学得也算是他的一个BUG吧,
对此,解决方法有三种:
1:
不用友元函数,用一个普通函数去调用它,这时候就要求在类里多定义几成员函数用于取值;
2:
把成友函数的定义放到类里面去,意思就是说在类里重载输入输出流操作符的时候就要把它给定义了,不
要到类的外面去定义他,不然的话就出错,说友元函数不能访问类的私有变量;
3:
VC++6.0下,只有用形如#i nclude <iostream.h>的形式包含头文件并且去掉using namespace std;这一 句后友元函数才能访问私有成员,这种说法不是很确定,不过有的这样好像不真的行,不过有的又不行,我也不清楚这到底是怎么回事.
反正不管怎么说,只要你遇到这种问题,第一种和第二种是肯定可以的,至于第三种方法,你看着办吧
|