像我这样工作2年多了,号称拥有2年C++经验,但其实如果细细的考察一番,恐怕对C++的掌握远远不及十分之一。其实这也是很多程序员的现状,只是觉得能够及解决问题,能够完成项目就OK,如果抱着这种态度,我想十年都不会有进步的。正是基于这种恐惧,我决定把自己再回炉一番,把基础再巩固一遍,查漏补缺。
在这一系列查漏补缺的文章中,我会把平时容易忽视,容易犯错,不好理解的知识点做一些总结归纳,把书本中讲述太简单的知识点做一些阐述。
既然是查漏补缺嘛,大家平时接触较多的东西就不累述了,总之,力求精简有用。
有元(friend)
对于大多数新手C++程序员,这是一个几乎不会用到的特性,而我们理解它也仅仅是为了看懂大神们的代码!记得上学时老师跟我们讲,最好不要用到这些容易出错不好掌握的特性,所以我们也像抛弃goto一样抛弃了它。其实“存在即合理”,既然它依旧存在于C++中,肯定是大有用处的。
知识要点:原书中感觉例子不是很清楚,自己在下面重新阐述了。
必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元。
解释:例如下面代码要先定义Y,才能在x中设Y为友元。但是在test文件中不用包含Y的头文件
友元声明将已命名的类或非成员函数引入到外围作用域中。
解释:下列x将Y设为友元,所以x的外围作用域中的class z也可以直接使用Y 而不用包含头文件来声明Y。
友元函数可以在类的内部定义,该函数的作用域扩展到包围该类定义的作用域
解释:代码中的f(x xx)定义在x内部,但它的作用于和Y一样,也可以被z使用。f()和普通的非类成员函数的区别是f()可以访问x的私有成员a;
file Y.h
class Y
{
int i;
};
file tes.h
class x
{
friend class Y;
friend int f(x xx){return xx.a;}//它可以访问到x的私有成员
private:
int a;
};
int f(x xx);
class z
{
Y *ymem;
x *xmem;
int g(){return ::f(*xmem);}
};
类必须将重载函数集中每一个希望设为友元的函数都声明为友元:
解释:如果一个将一个函数设为友元,并不意味着把它的重载函数也设为了友元。例如friend void fun();并不意味着重载函数fun(int a, int b)也是友元对 friend关键字来讲,重载是无效的,如果你希望所有的重载函数都友元,那就都friend一边吧!
友元的继承,一句话友元关系不能继承。基类的友元对派生类的成员没有特殊访问权限。
如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。
请看下面链接,该文中犯了一点小错,友元针对的是private属性而言的,看看评论就知道呢
http://blog.youkuaiyun.com/shandianling/article/details/7469361
基础知识:
“在某些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍然阻止一般的访问,这是很方便做到的”这句话阐述了友元的作用,就是为了访问私有成员嘛!
友元有2种形式,文章将友元分为“友元函数”“友元类”,而其中友元函数则又分为“类的友元函数”“非类的有原函数”
友元类:将一个类声明为其他类的友元,此类可以访问被友元类的私有成员
类的友元函数:将一个类(A)的函数(f()) 作为其他类(B)的友元,那么在这个类中仅仅只有A::f()可以访问B中的私有成员class Screen { // Window_Mgr members can access private parts of class Screen friend class Window_Mgr; };
class Screen
{
// Window_Mgrmust be defined before class Screen
friend Window_Mgr& Window_Mgr::relocate(Window_Mgr::index, Window_Mgr::index, Screen&);
};
当我们将成员函数声明为友元时,函数名必须用该函数所属的类名字加以限定。