现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

C++友元关系和类的静态成员概念和使用

2012-07-07 07:38 工业·编程 ⁄ 共 3777字 ⁄ 字号 暂无评论

一:C++友元关系:
1.类对于成员的封装(public, private, protected)
    1).封装性的优势:
        有效地保护了对象的内部细节,使得对象的使用和对象的实现分开,互相不产生影响。
    2).封装性的缺陷:
         1、C++为实现对象的封装,必然会做一些额外的工作,从而导致程序的效率下降。
   (调用成员函数来访问成员的时间开销降低了程序的执行效率)
         2、一个对象封装的太好,也会让该对象很难使用,也很难实现。
    3).封装性缺陷的弥补:
          C++提供了友元(friend)来解决由封装性带来的问题。
      friend修饰使其为有友元函数或友元类,其应用于比较特殊的情况(如提高效率),不提倡过度使用。

2.友元关系的分类:     
一个类可以声明一个友元关系,一起来共享类中的所有成员。
    1.友元类:友元是一个类.
   在类中可把另一个类声明为友元类,如类B是类A的友元类,则类B中的所有成员函数都是类A的友元函数,都可以访问类A的私有和保护成员。
    2.友元函数:是在类中由关键字friend修饰的非成员函数。

3友元函数的特点:
     第一、友元函数可以直接通过对象名访问类的私有和保护成员,可以像普通函数一样在任何地方调用。
       不是该类的成员函数,可以是一个普通的函数,也可以是其他类的成员函数。
     (朋友虽然不是家庭的成员,但容许到我们家里访问一样)
     第二、友元函数不属于任何类,因此可以放在类说明的任何位置,既可以在public区,也可以在private区。
     (友元函数看看作是类的部分接口,建议出现在public的部分)
     第三、友元函数不需要通过对象或对象指针来调用,可以直接调用即可。
    
4.友元函数的缺点:
      第一:使用友元波坏了封装性,降低了程序的可读性,因此应酌情使用.
      第二:友元函数中没有this指针(非类的成员函数),故必须通过函数参数来传递对象.

实例:

//类声明文件:sclass2_16.h 
 
#ifndef __SCLASS2_16_H__  
#define __SCLASS2_16_H__ 
 
#include<iostream> 
using namespace std; 
 
class CSample1 
{       
public: 
CSample1( void ){ };          //空构造函数 
 
//将类CSample2声明为类CSample1的友元类(friend class),相当于类CSample2的所有成员函数都是类CSample1的友元函数,即可以访问其所有成员. 
    friend class CSample2; 
 
void SetI(int t) 

i = t; 

 
int MemberFunc( void )       //成员函数 

return i; 

 
//友元函数直接访问CSample类的私有数据成员i,即一个类可以声明一个友元关系,一起来共享类中的所有成员 
 
friend void FriendFunc ( CSample1 * cp, int a ) //增加一个对象指针参数 

    cp->i = a;                     //对象指针参数为i指明当前所属对象 

 
private: 
int i; 
}; 
 
 
class CSample2 

public: 
CSample2( void ) {} 
 
    void ShowCSample1() 

CSample1 ss1; 
ss1.SetI(4); 
cout << "ss1.i=" << ss1.i << endl; 

 
    void ShowCSample1(CSample1 s1) 

cout << "s1.i=" << s1.i << endl; 

private: 
 
 
}; 
 
#include"sclass2_16.h" 
 
void main( void ) 

        CSample1 s1; 
s1.SetI(1); 
 
CSample1 *p1 = new CSample1;         //创建一个对象指针并初始化 
 
//友元函数不需要通过对象或对象指针来调用,可以直接调用即可。 
FriendFunc(p1, 2);                 //p指针所指的对象的i被赋值为2 
 
cout << "i=" << p1->MemberFunc()<<endl; 
 
delete p1;                         //释放指针p1 
 
CSample2 s2; 
 
s2.ShowCSample1(); 
 
s2.ShowCSample1(s1); 
 
//cout << "s1.i=" << s1.i << endl; 
 
}
 

二:类的静态数据成员:
1.类的静态成员存在的必要性:
          为对象提供了一个相互通信的方法
2.类的静态成员的特点:
   类的静态static成员拥有一块单独的存储区,与具体的对象没有关系,只属于类,该类的所有对象都共享这块静态存储空间.
3.类的静态成员的分类:
  1).类的静态数据成员:
   概念:数据成员名声明的时候加关建字statis,可以用于对象间的数据共享.
   定义格式:  static int s_iCount;  (类内定义)
   初始化:  int CCompanyStaff::s_iCount = 1001; (类外初始化)
   访问方式:  CCompanyStaff::s_iCount  (在所属类中直接使用) 或者 对象名.变量名.
   特点:
     类的静态数据成员不可以在类内进行初始化(因其不属于某个对象,否则没创建一个对象其就会被初始化一次,失去了对象间数据共享的意义).
     类的静态数据成员可以通过对象名来访问(因其被所有同类的对象共有).
     类的静态数据成员可以起到全局变量的作用.可以用于对象间的数据共享.但其优于全局变量:
        静态数据成员可以受private,protected修饰,实现信息的隐藏.而全局变量不行.
        静态数据成员名不进入全局命名空间,不存在与其他全局变量名冲突的问题.
      2).类的静态成员函数:
   概念:成员函数声明的时候加关建字statis,它的作用主要是访问和操作同类中的静态数据成员.
   特点:
     类的静态成员函数主要使用类的静态数据成员,静态成员函数一般不访问普通数据成员.
     静态成员函数是是类的非成员函数,它属于整个类,也为同类中所有对象共同拥有。
     静态成员函数没有this指针,所以必须通过传递对象引用来实现对其非静态成员的访问.同友元函数
访问对象的成员的情形相同.而且即使没有两者都没有this指针指明当前的所属对象,但可以通过类名或对
象名来实现对它的访问。
   访问方式:
     类名::函数名() 或者 对象名.函数名() 两种方式.
4.类的静态成员的案例代码:
头文件--类声明文件:sclass2_15.h
[cpp] view plaincopyprint?
#ifndef __SCLASS2_15_H__  
#define __SCLASS2_15_H__ 
 
#include<iostream>    //包含头文件。使用iostream库 
using namespace std;  //使用std名字空间 
 
class CDemo 

public: 
     
    CDemo( int i=0 ):m_i(i) 
    { 
        j = m_i; 
    } 
 
    //定义一个静态成员函数实现对静态数据成员j的操作 
    static int incr(CDemo &cdemo)       
    { 
        return ++j; 
        cdemo.m_i++; 
    } 
 
    //静态数据成员的定义 
    static int j; 
     
private: 
    int m_i;                  
       
}; 
 
//静态数据成员的初始化 
int CDemo::j = 0;            
 
#endif   //结束编译预处理 

主文件:smain2_15.cpp

#include"sclass2_15.h"  //包含类声明文件 
 
void main( void ) 
{    
    CDemo cdemo; 
 
    cout<<endl; 
 
    cout<<"类的静态数据成员的访问"<<endl; 
    CDemo::j = 1; 
    cout<<"CDemo::j = "<<CDemo::j<<endl;\ 
 
    cout<<endl; 
 
    cout<<"静态成员函数的访问1:类名::函数名()"<<endl; 
    cout << "CDemo::incr(cdemo) = " << CDemo::incr(cdemo) << endl;    
     
    cout<<endl; 
 
    cout<<"静态成员函数的访问2:对象名.函数名()"<<endl; 
    cout<<"cdemo.incr(cdemo) = "<<cdemo.incr(cdemo)<<endl; 
      

给我留言

留言无头像?