C++中的友元关系浅析

作者:小菜 更新时间:2025-03-16 点击数:
简介:在封装中C++类数据成员大多情况是private属性;但是如果接口采用多参数实现肯定程序效率;然而这时候如果外界需要频繁访问这些私有成员,就不得不需要一个既安全

【菜科解读】

在封装中C++类数据成员大多情况是private属性;但是如果接口采用多参数实现肯定程序效率;然而这时候如果外界需要频繁访问这些私有成员,就不得不需要一个既安全又理想的 后门 友元关系;

C++中提供三种友元关系的实现方式,友元函数、有缘成员函数、友元类。

友元函数:既将一个普通的函数在一个类中说明为一个friend属性;其定义(大多数会访问该类的成员)应在类后;

友元成员函数:既然是成员函数,那么肯定这个函数属于某个类,对了就是因为这个函数是另外一个类的成员函数,有时候因为我们想用一个类通过一个接口去访问另外一个类的信息,然而这个信息只能是被它授权的类才能访问;那么也需要用friend去实现;这个概念只是在声明的时候少有变化;

友元类:友元类声明会将整个类说明成为另一个类的友元关系;和之前两种的区别是集体和个人的区别;友元类的所有成员函数都可以是另一个类的友元函数;

值得注意的是友元关系是单向的,有点像我们恋爱中出现的单相思 O( _ )O,单向关系就是说如果A被说明称B的友元关系,那么只能说A是B的友元,并不代表B是A的友元;其次在多数情况下友元关系的函数都会访问它被说明中类的成员,这时候应该将函数定义在类的后面;

下面给一个简单的例程代码;

1 #include 2 3 using namespace std;4 5 class B;6 7 class A{8 private:9 int x;10 public:11 A();12 void display(B &);13 };14 15 class C;16 17 class B{18 private:19 int y;20 int z;21 public:22 B();23 B(int, int);24 friend void A::display(B &);//友元成员函数25 friend void display(B &);//友元函数26 friend class C;//友元类27 };28 29 class C{30 private:31 int sum;32 void calc(B &);33 public:34 C();35 void display(B &);36 };37 38 //必须在友元关系的类后进行定义39 void display(B &v)//友元成员函数40 {41 cout x = 0;47 }48 49 void A::display(B &v)//友元成员函数50 {51 this->x = v.y + v.z;52 cout x y = 0;58 this->z = 0;59 }60 61 B::B(int y, int z)62 {63 this->y = y;64 this->z = z;65 }66 67 C::C()68 {69 sum = 0;70 }71 72 void C::display(B &v)73 {74 this->calc(v);75 cout C++,中的,友元,关系,浅析,在,封装,中,C++,类,

Javascript中的“作用域链”知识分享

7 for(var i = 0; i发生了什么事情很多人都可能知道上例的执行结果,但是不是所有人都明白为什么会是这样的结果,包括我自己。

名词解释活动对象:一次函数调用开始的时候,javascript解释器会收集函数体中的所有局部变量(以var形式声明的变量),将这些局部变量存储到一个称为“活动对象”的对象里,所有变量都初始为undefined。

代码示例1 var fun = function(){2 alert(name);3 var name = ‘段光伟‘;4 }当执行这个函数时候时(fun()),函数体还没执行到,当前的活动对象为[{ name: undefined }],因此fun()执行的结果为:函数的[scope]属性:每个函数在定义的时候(生成函数实例的时候)都会分配一个[scope]属性,这个属性指向的当前的“作用域链”。

这个属性开发人员是访问不到的,只有javascript能访问。

作用域链:当函数调用时,javascript引擎会维护一个这次调用的作用域链,这个作用域链条是函数的[scope]指向的作用域链加上函数调用时的活动对象,形式如[ 活动对象, 函数定义时的作用域链条]。

代码示例 1 var a = 1; 2 //步骤1:[ { a: 1, outer: undefined } ] 4 var outer = function(){ 5 //步骤3:[ { b: undefined, inner: undefined } ,{ a: 1, outer: function } ] 6 var b = 2; 7 var inner = function(){ 8 //步骤4:[ {}, { b: 2, inner: function } ,{ a: 1, outer: function } ] 9 return a + b;12 //步骤3:[ { b: 2, inner: function } ,{ a: 1, outer: function } ]13 return inner();16 //步骤2:[ { a: 1, outer: function } ]17 outer();作用域链规则规则1javascript一般运行在一定的宿主中,每个宿主都会提供一个“全局对象”,或者叫“全局活动对象”,这个全局对象是所有作用域链的根节点。

规则2“取值操作”(如:alert(xxxVar))的规则是,沿着作用域链依次查找名称为“xxxVar”的变量,返回第一个找到的值,如果找不到就抛出异常(ReferenceError: xxxVar is not defined)。

规则3“赋值操作”(如:xxxVar = ‘段光伟‘)的规则是,沿着作用域链依次查找名称为“xxxVar”的变量,覆盖第一个找到的值,如果找不到就将“xxxVar”添加到全局对象中。

备注“闭包”这个概念就是通过“作用域链”实现的,而C#是通过编译器实现的,.NET并不支持。

Javascript,中的,“,作用域链,”,知识,分享,代

Ecplise编译Cygwin环境、使用CDT插件开发C/C++

借助Ecplise的强大功能,我们可以通过给Ecplise增加CDT插件来开发C/C++程序,下面是我配置CDT插件的总结过程,主要为了方便以后练习一些Demo程序时使用。

编译环境采用的是Cygwin。

使用Ecplise4.2 + CDT8.1.2 +Cygwin2.774。

建议先阅读第6条的注意事项。

强烈介意:先安装配置cygwin再安装cdt插件一、具体安装步骤为了保证安装顺利,请按以下步骤来进行。

1、安装Cygwin下载地址:http://cygwin.com/setup.exe官网:http://cygwin.com/下载好后,点击setup.exe进行安装,出现如下图所示界面 点击“NEXT”后我们看到如下界面:我们看到有三种安装模式:Install from Internet,这种模式直接从Internet安装,适合网速较快的情况;Download Without Installing,这种模式只从网上下载Cygwin的组件包,但不安装;Install from Local Directory,这种模式与上面第二种模式对应,当你的Cygwin组件包已经下载到本地,则可以使用此模式从本地安装Cygwin。

从上述三种模式中选择适合你的安装模式,这里我们选择第一种安装模式,直接从网上安装,当然在下载的同时,Cygwin组件也保存到了本地,以便以后能够再次安装。

选中后,点击“下一步”。

这一步选择Cygwin的安装目录,以及一些参数的设置。

默认的安装位置是C:\cygwin\,你也可以选择自己的安装目录,然后选择“下一步”,这一步我们可以选择安装过程中从网上下载的Cygwin组件包的保存位置,选择完以后,点击“下一步”,这一步选择连接的方式,选择你的连接方式,然后点击下一步,会出现选择下载站点的对话框,如下图所示,此步选择第一个163提供的镜像网站就可以,国内下载速度挺快,如果有其他镜像,可以输入URL后,点击“Add”进行添加,然后再在列表中选中。

选择完成后,点击“下一步”,进过下载几个文件后显示如下界面下面就在这个界面中下载我们需要编译C/C++代码的Packages,我们只需要下载“Devel”分支下几个包就可以了,gcc,gcc-core,gcc-g++,gcc-mingw-core,gcc-mingw-g++,make ,gdb,binutils。

在上图的search框中输入gcc,程序会自动进行搜索,如下图,通过选择“Devel”分支下的包,找到安装我们需要的包,然后点击Skip来选择最新的安装包这是已经成功安装最新版本包后的图示,大家单击“Skip”来选择最新版本的安装。

同理,输入“make”后,选择“Devel”分支下的包,下载如图所示的包:输入“gdb”后,选择“Devel”分支下的包,下载如图所示的包:输入“binutils”后,选择“Devel”分支下的包,下载如图所示的包:选完以后,我们选择下一步,进入安装过程,如下图所示,安装的时间依据你选择的组件以及网络情况而定。

安装完成后,安装程序会提示是否在桌面上创建Cygwin图标等,点击完成退出安装程序。

2、配置Windows的环境变量熟悉Java开发环境的都应该知道怎么找到环境变量,实在不知道的去百度下吧。

将cygwin\bin目录加入到环境变量PATH中。

然后,打开cmd命令行窗口,分别试一下gcc , g++命令。

如果显示“访问被拒绝” (access denied), 进入cygwin安装目录\bin下检查g++.exe, gcc.exe是否只有1k大小,如果是,那么文件是符号链接,那么把文件重命名一下(备份)。

然后把g++-3.exe(或者g++-4.exe)拷贝一份,重命名为g++.exe。

把gcc-3.exe拷贝一份,重命名为gcc.exe。

3、下载Ecplise CDT插件下载地址:http://www.eclipse.org/cdt/downloads.php参考:Ecplise插件的安装的四种方法。

或者通过Ecplise自动升级功能进行安装,如下图所示:添加地址:http://download.eclipse.org/tools/cdt/releases/juno4、配置Ecplise的C/C++开发环境(1)设置Ecplise与Cygwin的路径映射按以下步骤打开Ecplise:Window -> Preferences->C/C++->Debug-> Common Source Lookup Path -> add -> new "Path Mapping".映射方法,如下图:eclipse中调试时,由于GDB使用的unix格式的路径,而eclipse使用的是windows路径,导致找不到匹配的代码, 把linux的路径映射windows的路径:比如 /cygwin/c 映射成 C:\ 。

(2)配置C/C++的"Makefile Project",选择“PE Windows Parser", 和”Cygwin PE Parser" 两项。

5、在Ecplise中创建工程编写C/C++代码(1)创建C/C++工程点击”Next“,显示如下图:点击”Next“,显示如下图:点击”Finish“完成创建。

当编写好代码后,可以对你的工程进行编译,点击“Project”选项下的"Builder Project"项目即可。

编译后的工程,如下图所示:此时是成功编译后“Consloe”控制台的显示画面。

点击上面选中的,然后点击鼠标右键,选择“Run”,即可运行程序。

此时控制台即可打印出文字了。

到此我们就完成了Ecplise + CDT + Cygwin开发环境的配置,以后你就可以享用其方便的功能了。

6、常见问题1、Eclipse下的CDT创建C++项目时候,不能自动生成includes文件夹有两种解决方法:(1)打开Window -> Preferences->C/C++->Environment,如下图所示,添加两个环境变量将C_INCLUDE_PATH 设为 /usr/include将CPLUS_INCLUDE_PATH 设为 /usr/include/c++如果在Cygwin的/usr/include/目录下没有c++这个目录,可以从\cygwin\lib\gcc\i686-pc-cygwin\3.4.4\include\c++拷贝一个到目录下,或者直接添加这个目录都可以。

此步也可以解决代码中提示的显示信息”Unresolved inclusion:“问题,尽管不影响编译,只是无法定位头文件中的符号。

(2)在Windows里面,加入环境变量CPLUS_INCLUDE_PATH 和C_INCLUDE_PATH,并都设置成,安装的Cygwin的对应lib路径:D:\cygwin\lib然后再新建C/C++项目的时候,就可以自动生产Includes文件夹了。

2、用eclipse 建立编译C++工程出现错误提示 “symbol could not be resolved”问题原因:是debug下的source lookup path没有映射正确。

解决办法:window -> preferences -> C/C++ -> debug -> source lookup path > Path Mapping\cygdirve\c C:\用cygwin下的c盘来替代当前的C盘 来查找需要的库文件,如果你的Cygwin安装在C盘,则映射C盘,如果安装在D盘,则映射为\cygdirve\d D:\,其他盘同理。

3、用eclipse 建立编译C++Debug工程出现错误提示以下错误依然是上面映射的问题,打开Cygwin自带的“Cygwin Terminal”,然后输入以下命令“mount”如图所示:上面就是我们设置的映射,如果没有你的Ecplise的Workspace所在的盘的位置的映射,请按照上面的说明进行添加,即可调试成功。

例如,我的Workspace在D:盘下,则我想调试程序,必须映射到D盘的位置。

4、解决Eclipse的CDT编写的c/c++程序的运行结果不能输出到console的问题(1)设置“Debug Configurations"里的“Environment”选项,添加PATH,指定X:\cygwin\bin的路径。

如图所示(2)如果build不能通过(编译正常通过后会出现类似下面的输出)**** Build of configuration Debug for project Test ****make allmake: Nothing to be done for `all‘.**** Build Finished ****请按照上面步骤重新安装。

Ecplise,编译,Cygwin,环境,、,使用,CDT,

加入收藏
               

C++中的友元关系浅析

点击下载文档

格式为doc格式

  • 账号登录
社交账号登录