积极答复者
关于友元关系,出现一个奇怪的问题

问题
-
今天进行关于友元friend代码测试的时候发现的一个问题。
测试环境:Visual studio 2012
测试代码段1:
// classes_as_friends1.cpp #include <iostream> //using namespace std; // compile with: /c class B; class A { public: int Func1( B& b ); private: int Func2( B& b ); }; class B { friend int A::Func1( B& ); private: int _b; // A::Func1 is a friend function to class B // so A::Func1 has access to all members of B //friend int A::Func1( B& ); }; int A::Func1( B& b ) { return b._b; } // OK //int A::Func2( B& b ) { return b._b; } // error C2248 int main() { A obj1; B obj2; obj1.Func1(obj2); return 0; }
上面的代码段中“b._b”在VS2012中提示语法类错误,但是可以进行正常编译和运行。
注:此段代码未经任何影响结果的修改。
测试代码段2:
// 友元类成员函数不好使 #ifndef DEBUG #define DEBUG #include <iostream> using namespace std; class ClassB; class ClassA { friend int ClassB::set_value(ClassA); //提示错误 friend int ClassB::get_value(ClassA); private: int varA; public: }; class ClassB { //friend int ClassB::set_value(ClassA); //friend int ClassB::get_value(ClassA); private: int varB; public: int set_value(ClassA); int get_value(ClassA); }; int ClassB::set_value(ClassA objA) { int temp(0); this->varB = objA.varA; temp = objA.varA; return temp; } int ClassB::get_value(ClassA objA) { int temp = this->set_value(objA); return temp; } class ClassC : public ClassA { private: public: }; int main() { return 0; } #endif //!DEBUG
上面代码段中“this->varB = objA.varA;”提示语法错误,并且在VS2012中无法正常编译通过。
注:此段测试代码完全仿照代码段2进行编写。
问题:类似的代码段却出现不同的问题,真是令我很费解,不知道有没有人有兴趣一起跟我研究下原因。
另外,上面的代码把“friend int ClassB::set_value(ClassA);” 换成“friend class ClassB;”就可以正常通过编译并且运行。
煮酒论英雄
答案
-
修改了一下,这样就可以编译过去了:
using namespace std; class ClassA; class ClassB { //friend int ClassB::set_value(ClassA); //friend int ClassB::get_value(ClassA); private: int varB; public: int set_value(ClassA); int get_value(ClassA); }; class ClassA { friend int ClassB::set_value(ClassA); //提示错误 friend int ClassB::get_value(ClassA); private: int varA; public: }; int ClassB::set_value(ClassA objA) { int temp(0); this->varB = objA.varA; temp = objA.varA; return temp; } int ClassB::get_value(ClassA objA) { int temp = this->set_value(objA); return temp; } class ClassC : public ClassA { private: public: }; int main() { return 0; }
Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
- 已标记为答案 仙人球球 2013年2月19日 14:50
-
你可以做这样一个小测试:
在VisualEleven修改过的那段代码中,在A类中添加一个函数,并将这个函数作为B类的友元函数,则编译失败。
根据这个测试结果,我认为,如果你把B类的成员函数作为A类的友元函数,则B类的定义必须在A类之前,仅仅做前置声明是不够的。
Damon Zheng
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- 已标记为答案 Damon ZhengModerator 2013年2月25日 4:51
全部回复
-
修改了一下,这样就可以编译过去了:
using namespace std; class ClassA; class ClassB { //friend int ClassB::set_value(ClassA); //friend int ClassB::get_value(ClassA); private: int varB; public: int set_value(ClassA); int get_value(ClassA); }; class ClassA { friend int ClassB::set_value(ClassA); //提示错误 friend int ClassB::get_value(ClassA); private: int varA; public: }; int ClassB::set_value(ClassA objA) { int temp(0); this->varB = objA.varA; temp = objA.varA; return temp; } int ClassB::get_value(ClassA objA) { int temp = this->set_value(objA); return temp; } class ClassC : public ClassA { private: public: }; int main() { return 0; }
Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
- 已标记为答案 仙人球球 2013年2月19日 14:50
-
你可以做这样一个小测试:
在VisualEleven修改过的那段代码中,在A类中添加一个函数,并将这个函数作为B类的友元函数,则编译失败。
根据这个测试结果,我认为,如果你把B类的成员函数作为A类的友元函数,则B类的定义必须在A类之前,仅仅做前置声明是不够的。
Damon Zheng
MSDN Community Support | Feedback to us
Develop and promote your apps in Windows Store
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- 已标记为答案 Damon ZhengModerator 2013年2月25日 4:51