类的提前声明
回忆函数的原型声明
#include <iostream> using std::cout; using std::endl; void test(); int main() { test(); return 0; } void test() { cout << "函数的提前声明!" << endl; }
类和函数也是类似的,有时也需要提前声明
class B; //提前声明 class A { //class B }; int main() { void ff(B &); //RIGHT可以声明引用 B *p_b = NULL; //RIGHT可以定义指针! //B bb; //ERROR不能定义对象 system("PAUSE"); return 0; } class B { }; void ff(B &) {}
注意:
提前声明不能定义该类的对象
仅能定义该类的指针或引用
为何引入友元?
通常一个类中的非公有成员是无法被该类的非成员函数直接访问的!如果我们将函数声明为这个类的友元,该函数将能访问该类的非公有成员!
友元非成员函数
概念:将类外的函数(顶层函数)声明为友元函数
声明方法:
friend 类型 函数名(形参表);
在类中用friend声明函数!
#include <iostream> #include <string> using namespace std; class Time { public: Time(int aH=0, int aM=0, int aS=0); friend void display(Time&); private: int hour; int minute; int second; }; Time::Time(int aH, int aM, int aS) { hour=aH; minute=aM; second=aS; } void display(Time &t) { cout<<t.hour<<":"<<t.minute<<":"<<t.second<<endl; } int main() { Time t(12,30,54); display(t); system("PAUSE"); return 0; }
注意:
①友元函数应该声明在类体内,且friend仅在声明时使用,只出现一次。
②调用方式和普通全局函数一样。
③友元全局函数的声明语句就是函数的声明语句。
④友元全局函数也可以在类内定义,此时编译环境仍将其视为全局函数,且定义就相当于声明而不需要提前声明。
⑤一个全局函数可以被声明为多个类的友元。
⑥多个全局函数可以被声明为一个类的友元。
友元成员函数
概念:一个类的成员函数可以被声明为另一个类的友元。
声明方法:
friend 类型 类名::函数名(形参表);
#include <iostream> #include <string> using namespace std; class Atest; //提前声明 class Btest { public: Btest(int aX = 4):m_dVal(aX){} void display(Atest &aVal); private: double m_dVal; }; class Atest { public: Atest(int aX = 3):m_iVal(aX){} friend void Btest ::display(Atest &aVal); private: int m_iVal; }; void Btest::display(Atest &aVal) { cout << "Atest.m_iVal = " << aVal.m_iVal << endl; cout << "Btest.m_dVal = " << m_dVal << endl; } int main( ) { Atest testa; Btest testb; testb.display(testa); getchar( ); return 0; }
友元类
为什么引入友元类?
如果一个类A中的成员函数都希望访问类B的非公有成员,我们可以将A声明为B类的友元类
声明方法:
friend 类名;
class Date; class Person { friend Date;//在person类中的任意位置 }; class Date { };
注意:
①友元不具备传递性!
②友元关系单向的!
③友元关系破坏了信息隐蔽的原则,但友元关系也提供了数据共享的一种方法。
④友元不受访问限定符限制。