const:
所修饰的对象或变量不能改变,修饰函数时,该函数不能修改在函数外面声明的变量,也不能调用任何非const函数。在函数声明和定义时都要加上const,放在函数参数列表的最后一个括号后。
const_cast:
去除变量或对象的const限定,格式为const_cast<int *>(const_p)
dynamic_cast:
dynamic_cast用于类继承层次间的指针或引用转换。主要还是用于执行“安全的向下转型“。向上转型本身就是安全的。
enum:
enum(枚举)类型,给出一系列固定的值,只能在这里面进行选择一个。
explicit:
explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的。e.g., CxString(int size){size_ = size}允许CxString tmp = 10;这样子的构造等同于CxString tmp(10), 与CxString tmp = ”cc“;混淆。
export:
为了访问其他编译单元(如另一代码文件)中的变量或对象,对普通类型(包括基本数据类、结构和类),可以利用关键字 extern,来使用这些变量或对象时;但是对模板类型,则必须在定义这些模板类对象和模板函数时,使用标准 C++ 新增加的关键字 export(导出)。
e.g.
// out.h:(声明头文件——只包含out函数的声明信息)
template<class T> void out (const T& t);
// out.cpp:(定义代码文件——包含out函数的声明[通过include]和定义等全部信息)
#include <iostream>
#include “out.h”
export template<class T> void out (const T& t) {std::cerr << t;}
//user.cpp:(用户代码文件——包含函数的声明头文件后就可以使用该函数)
#include “out.h”
// 使用out()
extern: extern(外部的)声明变量或函数为外部链接,即该变量或函数名在其它文件中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。
//在test1.h中有下列声明:
#ifndef TEST1H //防止头文件的重复引用
#define TEST1H
extern char g_str[]; // 声明全局变量g_str
#endif
// 在test1.cpp中
#include "test1.h"
char g_str[] = "123456"; // 定义全局变量g_str
//以上是test1模块, 它的编译和连接都可以通过,如果我们还有test2模块也想使用g_str,只需要在原文件中引用就可以了
#include "test1.h"
void fun2() { cout << g_str << endl; }
friend: 友元可以访问与其有 friend 关系的类中的 private/protected 成员,通过友元直接访问类中的 private/protected 成员的主要目的是提高效率。
https://www.cnblogs.com/honeybusybee/p/5259265.html
inline: 在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数。
e.g.
#include <stdio.h>
//函数定义为inline即:内联函数
inline char* dbtest(int a) {
return (i % 2 > 0) ? "奇" : "偶";
}
int main(){
for (i=1; i < 100; i++) {
printf("i:%d 奇偶性:%s /n", i, dbtest(i));
}
}
在内部的工作就是在每个for循环的内部任何调用dbtest(i)的地方都换成了(i%2>0)?”奇”:”偶”,这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗。
注意: 1. inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。
2. 内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。
mutable: 当类或者结构体中的某个变量被mutable关键字修饰时,即便这个结构体或者类被实例化为const类型,其中被mutable修饰的变量仍可以被修改。
e.g.,
typedef struct test {
mutable int iVal = 0;
}Test;
int main() {
const Test t;
t.iVal = 2;
}
register: 当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。
注意: 1. 只有局部变量才可以定义为寄存器变量
2. 建议型关键字,同inline,实际编译的时候可以并未成为寄存器变量。
reinterpret_cast:
static:
运行一个完整的程序。我们可将整个存储区分为四块:
(1)栈区:就比如局部变量,对应的函数参数等这些,调用完之后相应的内存会自己释放掉,很让人省心。
(2)堆区:堆来堆去的。得要人动手。所以得我们自己手动去分配和释放。像malloc(c),new(c++) ,delete 一下等等。
(3)全局数据(静态区):全局变量和静态变量是放在一个窝里面的。静态变量如果没有初始化,系统会自动初始化的。虽然系统会自动初始化,但是分房间的时候还是得分清楚的。所以最终是初始化的全局变量和初始化的静态变量分在一块区域,即同一个房间。未初始化的全局变量和未初始化的静态变量分在一块。程序结束时释放。
(4)最后就是代码区了
static的用法:
(a)如果用static修饰局部函数的变量。那么这个变量就是静态变量了。在主函数中,如果重复调用这个函数,那么里面的这个静态变量只会初始化一次。如果没有用static修饰,那么每次调用的时候都会对这个变量进行初始化。
(b)如果用static修饰全局的变量。那么在这个文件中所有的函数都可以使用这个变量。如果一个工程里面有a.c和b.c文件,static在a.c中定义的。那么b.c就用不了这个static修饰的变量。如果没有static修饰,只要加一个extern外部调用声明,就可以了。
(c)如果用static修饰全局函数,同上(b)。
(d)static修饰类中的变量。用static修饰之后,那么这个变量的内存就分配在了全局数据区了,并不和该类在同一片区域。所以static只会被初始化一次。
(e)static修饰类中的函数。那么该函数就变成了静态函数。静态函数不能访问非静态函数,非静态函数可以访问静态函数。访问静态函数可以用(.->),指针或者类名::三种方式访问。
static_cast:
static_cast < type-id > ( expression )
该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
① 用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
② 用于基本数据类型之间的转换,如把 int 转换成 char,把 int 转换成 enum。这种转换的安全性也要开发人员来保证。
③ 把空指针转换成目标类型的空指针。
④ 把任何类型的表达式转换成void类。
union: 不同的是 enum 实质上是 int 类型的,而 union 可以用于所有类型。
virtual: 基类的函数调用如果有virtual则根据多态性调用派生类的,如果没有virtual则是正常的静态函数调用,还是调用基类的。
纯虚函数: virtual ostream& print( ostream&=cout ) const = 0;
包含一个或多个纯虚拟函数的类被编译器识别为抽象基类。抽象基类不能被实例化,一般用于继承。抽象基类只能作为子对象出现在后续的派生类中
volatile: 用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错
网友评论