若无特殊说明,本博客所执行的C++标准均为C++11.
类是一种用户自定义类型,按照访问权限有三种类型的成员,声明形式如下:
class 类名称
{
public:
公有成员(成员函数)
//外部能够通过`对象.成员(成员函数)`的方式访问的成员(成员函数)
private:
私有成员(成员函数)
//对外部不可见的成员,外界无法访问,通常会通过公有成员函数提供访问接口,注意私有成员函数也算是私有成员,外部也访问不到
protected:
保护成员(成员函数)
//与private相似,差别表现在继承与派生时对派生类的影响不同
}
毕竟类是类型声明,所以和C中类型声明一样,应该放在头文件中。
而其中的成员函数,如果直接将函数体放在类中,编译器会默认认为其是inline
的,当然inline
本身也只是建议内联的关键字。
如果.h文件中的类声明里的成员函数只放置了函数声明,函数的实现放在对应的cpp文件中的话,需要使用域运算符进行限定,以让编译器知道你这个函数是哪个类的成员函数
返回值 类名称::函数名(参数)
{
函数体
}
类中成员命名习惯(规范)有两种,一种是m_
开头(微软的习惯);一种是以_
结尾(谷歌的习惯),二者均可。(个人更喜欢前者,毕竟C中经常使用类型缩写做变量名前缀)。
class和struct的区别,需要注意,在C++中,struct声明的也是类,区别在于
成员函数有一个隐含的附加形参,即指向该对象的指针,这个隐含的形参叫做this指针。使用this指针保证了每个对象可以拥有自己的数据成员(指向的内存不同),但处理这些成员的代码可以被所有对象共享。
C++中的作用域有以下几种:
{}
框定起来的块,变量和标识符的作用仅限于块内(如果没有extern
声明的话);extern
声明的话);{}
框起来的部分){}
框起来的部分),当然类成员函数定义时,可以用::
访问域内函数定义成员函数体。总结下来,其实就是文件作用域和块作用域{}
两个,需要注意的是,如果作用域内的作用域外有两个同名的变量,编译器通常会选择最内层的作用域(不过通常建议不要这么做,除非用::
域限定符特殊指明了变量所属的域)。
对于类来说,如果在类域的函数体定义内使用变量的话,编译器默认也是指类域内的变量优先。
C++中类必须先定义,才能够实例化。
两个类需要相互引用形成一个"环形"引用时,无法先定义使用。这时候需要用到前向声明。
注意: 前向声明的类在要把这个类定义成成员的类中不能实例化。
在C中相似的例子是链表定义时,我们需要在结构体定义中定义自己结构体的指针,通常需要一个结构体指针前向声明在结构体前面。
类似的便是在C++中如果想定义两个类相互中有对方的类作为成员的时候,有一个类必须定义在前,则另一个类需要使用前向声明,先声明有这个类,但没有定义,这样前面定义的类从才可以在成员中使用后面定义的类,但前面这个类定义后面这个类成员的时候不能定义实体,只能定义引用或者指针,毕竟前面只有一个声明,没有类的定义。
从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类的作用域外使用该类名时,需要加名字限定。
嵌套类中的成员函数可以在它的类体外定义(需要使用::
类限定符嵌套访问)。
需要注意的时,嵌套类本质上时平行的两个类,访问权限的从属关系(外面类的私有变量,里面的类访问不了;里面类的私有变量,外面类也访问不了)。嵌套类仅仅只是语法上的嵌入。
个人推测,这个嵌套类的作用很有可能是在单文件库中使用,通常单文件库只提供一个头文件,而对于某个类如果我不想让使用者包含这个头文件的时候接触到,可以通过嵌套类定义成私有的嵌套类成员,这样使用者不仅接触不到这个嵌套在里面的嵌套类成员,也接触不到这个嵌套类类型。
类也可以定义在函数体内,这样的类被称为局部类(loacl class)。局部类只在定义它的局部域内可见。
局部类的成员函数必须被定义在类体中。
局部类中不能有静态成员(毕竟局部类的作用域仅限于函数体,本质在代码实现的时候整个类都是在栈中分配的,作用域也仅限于函数体)。