再次学习,复习以往知识依然有所感受,将此记下。
陌生关键字
- explicit:explicit(显式的)的作用是"禁止单参数构造函数"被用 于自动型别转换,其中比较典型的例子就是容器类型。在这种类型的构 造函数中你可以将初始长度作为参数传递给构造函数。
- export:为了访问其他编译单元(如另一代码文件)中的变量或对象, 对普通类型(包括基本数据类、结构和类),可以利用关键字 extern,来使用这些变量或对象时;但是对模板类型,则必须在定义 这些模板类对象和模板函数时,使用标准 C++ 新增加的关键字 export(导出)。
- extern :extern(外部的)声明变量或函数为外部链接,即该变量或函数名在其它文件中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义(实现)。在文件内声明一个变量或函数默认为可被外部使用。在 C++ 中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前仅支持 C 转换标记,来支持 C 编译器链接。使用这种情况有两种形式:
extern “C” 声明语句
extern “C” { 声明语句块 } - mutable:mutable(易变的)是 C++ 中一个不常用的关键字。只能用于类的非静态和非常量数据成员。由于一个对象的状态由该对象的非静态数据成员决定,所以随着数据成员的改变,对像的状态也会随之发生变化。如果一个类的成员函数被声明为 const 类型,表示该函数不会改变对象的状态,也就是该函数不会修改类的非静态数据成员。但是有些时候需要在该类函数中对类的数据成员进行赋值,这个时候就需要用到 mutable 关键字。
- register :register(寄存器)声明的变量称着寄存器变量,在可能的情况下会直接存放在机器的寄存器中;但对 32 位编译器不起作用,当 global optimizations(全局优化)开的时候,它会做出选择是否放在自己的寄存器中;不过其它与 register 关键字有关的其它符号都对32位编译器有效。
- reinterpret_cast:用法:
reinpreter_cast (expression)
type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。 - typeid:指出指针或引用指向的对象的实际派生类型。
- typename :typename(类型名字)关键字告诉编译器把一个特殊的名字解释成一个类型。在下列情况下必须对一个 name 使用 typename 关键字:
1. 一个唯一的name(可以作为类型理解),它嵌套在另一个类型中的。
2. 依赖于一个模板参数,就是说:模板参数在某种程度上包含这个name。当模板参数使编译器在指认一个类型时产生了误解。 - union:union(联合),类似于 enum。不同的是 enum 实质上是 int 类型的,而 union 可以用于所有类型,并且其占用空间是随着实际类型大小变化的。
- volatile:volatile(不稳定的)限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下:
int volatile nVint; - asm (指令字符串):允许在 C++ 程序中嵌入汇编代码。
##简单线程
#include#include #include #include #include #include void f1(int n) { for (int i = 0; i < 5; ++i) { std::cout << "Thread " << n << " executingn"; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } void f2(int& n) { for (int i = 0; i < 5; ++i) { std::cout << "Thread 2 executingn"; ++n; std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } int main() { int n = 0; std::thread t1; // t1 is not a thread std::thread t2(f1, n + 1); // pass by value std::thread t3(f2, std::ref(n)); // pass by reference std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread t2.join();//等待线程结束后合并线程,同时在detach上,线程结束会自动的清理,看需求选择策略 t4.join(); std::cout << "Final value of n is " << n << 'n'; }
简单指针
- 如果所有未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值, 导致程序难以调试。
if(ptr) if(!ptr)基本I/O
基本概念
-
流:字节序列
-
输入:设备到内存
-
输出:内存流向其他
-
cout,cin,cerr,clog:标准输出流,标准输入,非缓存标准错误输出流,日志标准输出流。
##C++类的基本概念 -
一个派生类继承了所有的基类方法,但下列情况除外:
- 基类的构造函数、析构函数和拷贝构造函数。
- 基类的重载运算符。
- 基类的友元函数。
-
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的
-
输出运算符的重载:ostream &operator<<(ostream&output, const Distance &D )
-
同时对于I/O运算符的重载,只能使用引用的方式进行传参,I/O流只有一个
-
多态的存在解决了类之间的层次结构问题,最明显的是继承关系,基类和派生类之间的函数调用关系。
-
virtual:虚函数关键字,我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
- 注意,当父类的指针指向派生类的时候,调用相同的函数时可能会出现静态绑定的问题,virtual关键字就是用于解决静态绑定的问题。
- 同时,可以使用virtual来建立纯虚函数告诉编译器没有主体 ( = 0),类似于java中的interface关键字。
-
数据抽象是一种依赖于接口和实现分离的编程(设计)技术。
- 设计策略:
抽象把代码分离为接口和实现。所以在设计组件时,必须保持接口独立于实现,这样,如果改变底层实现,接口也将保持不变。
在这种情况下,不管任何程序使用接口,接口都不会受到影响,只需要将最新的实现重新编译即可。
- 设计策略:
-
文件流
- ofstream:用于打开文件
- ifstream:用于写入文件
-
异常处理
- throw:您可以使用 throw 语句在代码块中的任何地方抛出异常。throw 语句的操作数可以是任意的表达式,表达式的结果的类型决 定了抛出的异常的类型。
- try{…} catch(){}:使用try包裹容易发生异常代码块,关于异常Exception类是所有异常类的基类,在catch代码块中可以对异 常代码进行处理,如打印异常日志或者解决异常,确保程序不崩溃。



