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

一: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

#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;
	 
}
运行结果截图:




  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值