【c++】友元
一. 友元
二. 友元函数
三. 友元类
参考:
《c++从入门到精通》 人民邮电出版社
友元
在c++中,为了使得A类的私有成员和保护成员能被其他的类或其他成员函数访问,引入了友元的概念。好比,给类A找了个好朋友类B,那么类B 就可以访问类A的私有成员和保护成员。
友元,可以是一个普通函数,也可以是另一个类的成员函数,也可以是另一个类!
友元函数
当一个普通函数想访问一个类的私有、保护成员数据时,由于不许直接访问另一个类的私有、保护成员,必须通过调用公有成员函数来实现,因此访问效率很低。为了提高访问效率,c++允许在一个类中把一个普通函数(或另一个类的成员函数或另一个类)声明为一个友元函数(或友元类)。
友元 的关键字:friend。
友元函数实例:
//友元函数.cpp #include<iostream> using namespace std; class Cset { private: int x; int y; public: void set(int a,int b) { x=a; y=b; } void print() { cout<<"x="<<x <<" y="<<y <<endl; } // 友元函数 friend Cset add(Cset & a,int nOffset); }; Cset add(Cset & a,int nOffset) { Cset aTemp; aTemp.x=a.x+nOffset; aTemp.y=a.y+nOffset; return aTemp; } int main() { Cset m; m.set(4,5); cout<<"未调用友元函数前:"; m.print(); m=add(m,5); //调用友元函数 cout<<"调用友元函数后: "; m.print(); return 0; }
运行结果:
分析:
本例中定义了类Cset,在类中声明了友元函数add(),在类的外部对该函数进行了定义。
在main()中创建了对象Cset m,创建对象后调用m.set(4,5)设置x,y的值为4,5;然后调用友元函数add()实现了私有变量值x,y的修改。
一般,友元函数应注意:
(1)必须在类的定义中说明友元函数。在private、protected、public中都可以,位置不限。
(2)友元函数不是类的成员,因而不能直接引用对象成员的名字,也不能通过this指针引用对象的成员,而必须通过入口参数传递进来的对象名或对象指针来引用该对象的成员。因此,友元函数一般都带有一个该类的入口参数。
例:Cset add(Cset & a,int nOffset)
(3)当一个函数需要访问多个类时,应该把这个函数同时定义为这些类的友元函数。
友元类
不仅函数可以作为一个类的友元,而且一个类也可以作为另一个类的友元,这种类称为友元类。
友元类编程实例:
//友元类.cpp #include<iostream> using namespace std; class A { private: int x; static int y; public: void set(int a) { x=a; } void print() { cout<<"x="<<x <<" y="<<y <<endl; } // 友元类 friend class B; }; class B { private: A a; public: B(int m,int n) { a.x=m; a.y=n; } void print() { cout<<"x="<<a.x <<" y="<<a.y <<endl; } }; int A::y=1; //注意 int main() { A a; a.set(5); a.print(); B b(6,7); b.print(); a.print(); return 0; }
运行结果:
注意:在类中直接初始化静态变量,是error的。
class A { private: int x; static int y=1; // error! }
其中,static inty=1; 会报错:c++禁止在类中初始化 非const static 成员变量。
static变量只有一次初始化,不管在类中还是在函数中。类中定义的非const型的static变量,应在类外初始化。将上述改为:
class A { private: int x; static int y; // } int A::y=1; //注意在类外初始化
而若是const型的static变量,则可以直接在类中初始化。
class A { private: int x; static const int y=1; // OK }------------------------------------------- END -------------------------------------