const 是一个左结合的类型修饰符,它与其左侧的类型修饰符和为一个类型修饰符。const可以用于定义常量,可以限定函数的引用参数(因为传值的参数根本不用限定),可以限定函数返回值为引用的情况。还有一个用法是修饰类的成员函数。这样情况下,在类内的声明和类外的定义都要加上const。
还有一种情况是,声明类的const成员变量的时候,如何进行初始化。
在这种情况下,由于常量不能修改,所以只能在构造函数的初始化列表中进行复制初始化。如果同时声明为了static时可以在类外进行初始化,但此时不能加static关键字。
mutalbe的中文意思是"可变的,易变的",跟constant(既C++中的const)是反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量(mutable只能由于修饰类的非静态数据成员),将永远处于可变的状态,即使在一个const函数中。
我们知道,假如类的成员函数不会改变对象的状态,那么这个成员函数一般会声明为const。但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutable来修饰。
explicit:
explicit使用注意事项:
*explicit 关键字只能用于类内部的构造函数声明上。
*explicit 关键字作用于单个参数的构造函数。
* 在C++中,explicit关键字用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。
explicit关键字只能用于类内部的构造函数声明上。在类的定义体外部所做的定义上不能再重复它。
如果一个类或结构存在多个构造函数时,explicit 修饰的那个构造函数就是默认的
当构造函数被声明为explicit时,编译器将不使用它作为转换操作符。
explicit 关键字作用于单个参数的构造函数。
通常,除非有明显的理由想要定义隐式转换,否则,单形参构造函数应该为explicit。
friend:
(1) 类的friend函数可以访问类的private和protected成员。
(2) friend关系不能继承,基类的友元对子类的成员没有特殊访问权限,如果基类被授予友元关系,则只有基类具有特殊访问权限,其派生类不能访问授予友元关系的类。
(3) 派生类的friend函数可以访问派生类的一切变量,包括从基类继承下来的protected域中的变量,但对父类来说它不是friend。
(4) friend关键字只能出现在类定义内部,不可出现在外部。
inline:
(1) inline表示内联,即在函数调用出将函数内联地展开。
(2) inline既可以出现在类定义内部,也可以出现在外部。当在外部出现时必须定义在类定义的头文件中,因为调用函数时需要看到函数是什么样子。
static:
(1) static类成员属于整个类,不属于某个类对象。
(2) static成员遵循正常的公有/私有访问规则。
(3) 对于public static成员可以通过类名或对象名访问,对于private static成员则不可,须按照正常private成员访问规则进行访问。
(4) static成员函数可以访问static成员函数和变量,不可访问非static成员和函数,因为static成员是类的,而非static是对象的,类的产生先于对象,怎么能在对象为产生之间就调用它的数据呢。
(5) 非static成员函数既可以访问static成员又可以访问非static成员。
(6) 可以通过类名直接调用public static成员,或者通过对象名、引用或指针间接调用。注意此处指的是public static成员,不是private。
(7) static成员函数没有this指针,因为this指向的是对象。
(8) static成员函数不能声明为const或虚函数,因为此二者都是针对对象而言,此外static函数实际上是"加上了访问控制的全局函数",全局函数当然没有虚函数。但是static变量可以声明为const。
(9) static只用于类内声明,在类外定义时不能加static。
(10) static变量的初始化只能放在源文件中,如果放在头文件中可能会被重复定义。
(11) 在对static变量进行初始化时,可以忽略任何存取权限的束缚,例如:
double ClassA::m_a = 0.05; (注意假设ClassA::m_a是private, 则除了在定义static时可以这样写外,其它地方均不得如此)
(12) static成员变量不能再类内初始化,必须在类外定义时初始化(在源文件中),但是有个例外,const static成员可以在类内初始化,同时仍必须在类外进行定义,定义时无需加static,无需指定初始值,但必须加const修饰符。[这一条引自C++ Primer,4th Edition, P401,但是上机实验证明,如果已经在类内初始化,则就不须在类外定义,否则产生多重定义的变异错误,不知道是不是编译器的问题,我用的是VS2005]
(13) static成员可以被继承,父类的static变量和函数在派生类中依然可用,但是受访问控制,而且对static变量来说,派生类和父类中的static变量是共用空间的,这点在利用static变量进行引用计数时要注意。
静态成员函数不能够使用const和volatile修饰。
virtual:
在基类中被定义为virtual的函数,派生类重载该函数不需要再次显示说明该函数是virtual的。
inline, static, constructor三种函数都不能带有virtual关键字。
inline是编译时展开,必须有实体;
static属于class自己的,也必须有实体;
virtual函数基于vtable(内存空间),constructor函数如果是virtual的,调用时也需要根据vtable寻找,但是constructor是virtual的情况下是找不到的,因为constructor自己本身都不存在了,创建不到class的实例,没有实例,class的成员(除了public static/protected static for friend class/functions,其余无论是否virtual)都不能被访问了。
:
本意是"易变的",用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被寄存。