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

原创 2012年03月24日 18:34:16

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




C++访问类的私有成员变量的方法(友元函数、友元类)

// win32Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" class...
  • libaineu2004
  • libaineu2004
  • 2014年03月06日 11:28
  • 8856

C++之模板(友元函数+友元类+静态Static)

友元函数 友元函数分为友元全局函数和友元成员函数。 下面是一个友元全局函数的例子:class Coordinate { friend void printXY(Coordinate &c...
  • u013486414
  • u013486414
  • 2017年03月05日 20:57
  • 466

C++友元函数和友元类的使用基础

友元函数百度百科:       友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想...
  • zgrjkflmkyc
  • zgrjkflmkyc
  • 2013年03月13日 11:27
  • 4830

C++中如何声明 “友元类” 和 “友元函数”

调试平台:win7 vs2012 win32控制台终端项目 友元(friend) 字面义:顾名思义既然是朋友了,我的东西同样可以给你使用 书面语:将一个类的非公有成员(包括方法和成员变量)的访问权限赋...
  • comwise
  • comwise
  • 2013年11月05日 18:57
  • 2807

C++中友元类使用场合

在C++中我们可以將函数定义成类的友元函数,这样在函数中就可以访问类的私有成员。与函数相同,类也可以作为另一个类的友元类,在友元类中可以访问另外一个类的所有成员。 声明友元类的方法很简单,只需在类中...
  • Rongbo_J
  • Rongbo_J
  • 2015年04月17日 10:48
  • 3575

一个友元类使用误区(C++)

这个问题,我困扰了好一会。决定记录一下
  • qq_33850438
  • qq_33850438
  • 2016年12月09日 21:10
  • 1034

试图对C++友元函数,静态成员函数做个小结

友元函数个人小结
  • ghostjlq
  • ghostjlq
  • 2014年12月13日 22:28
  • 638

成员函数、友元函数和一般函数的区别-时间

/* *Copyright (c) 2016 *All rights reserved. *文件名称:test.cpp *作 者:史红浩 *完成日期:2016年...
  • jiaowohaohao
  • jiaowohaohao
  • 2016年05月09日 12:13
  • 1885

关于类中的成员函数和非成员函数(即友元函数)的选择

在定义类的成员函数时,经常遇到运算符重载的情况,wang
  • erpng
  • erpng
  • 2014年05月24日 21:11
  • 652

一个类的成员作为另一个类的友元函数

普通成员函数作为一个类的友元函数,以及一个类作为另一个类的友元类,都好...
  • jw903
  • jw903
  • 2014年08月27日 08:59
  • 1607
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++友元关系和类的静态成员概念和使用
举报原因:
原因补充:

(最多只允许输入30个字)