一、volatile介绍
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值。总结一句话就是volatitle 每次读取都是从内存当中读取最新的数据,而不是从寄存器中获取。在多线程的情况下类似 std::atomic_flag 原子操作。简单介绍一下 std::atomic_flag 用法,使得每一个线程可以单读的访问。
#include <thread>
#include <vector>
#include <iostream>
#include <atomic>
std::atomic_flag lock = ATOMIC_FLAG_INIT;
void f(int n)
{
for (int cnt = 0; cnt < 5; ++cnt) {
while (lock.test_and_set(std::memory_order_acquire)) // 获得锁
; // 自旋
std::cout << "Thread " << n << " count:" << cnt << std::endl;
lock.clear(std::memory_order_release); // 释放锁
}
}
int main(int argc, char* argv[])
{
std::vector<std::thread> v;
for (int n = 0; n < 4; ++n) {
v.emplace_back(f, n); //使用参数进行初始化
}
for (auto& t : v) {
t.join(); //等待线程结束
}
system("pause");
return 0;
}
二、assert 的用法
assert 名为断言 使用的时候需要添加#include<assert.h> 头文件,用于判定表达式是否是真,如果是真的就通过继续执行其他代码,如果是假的则会终止程序运行。如果加上 #define NDEBUG 则断言不可用,会忽略掉。
#include <stdio.h>
#include <assert.h>
#define NDEBUG // 加上这行,则 assert 不可用
int main()
{
int x = 7;
/* Some big code in between and let's say x
is accidentally changed to 9 */
x = 9;
// Programmer assumes x to be 7 in rest of the code
assert(x==7);
/* Rest of the code */
return 0;
}
三、extern 的用法
意指 c++ 和 c语言的区别,编译器对两种语言函数的编译生成的函数符合不一致,在c++中会携带函数名+函数传参类型,而C语言只有函数名,在C++ 代码中使用C语言的时候,告诉编译器此处代码按C语言方式进行编译,此时extern "C"
就起作用了:告诉链接器去寻找_add
这类的C语言符号,而不是经过C++修饰的符号。
四、struct 和 class 区别
在C语言中的struct 和在C++ 中的struct 还是会有区域别的
C语言中的struct 没有c++ 中的特性,且只能是复合类型的应用,不能包含函数,不能使用C++ 中的访问修辞,在C语言中使用struct时,在定义时必须添加struct 关键字,如果结构体名称和函数名称一致时,二者不冲突。
#include<stdio.h>
struct Base { // public
int v1;
// public: //error
int v2;
//private:
int v3;
//void print(){ // c中不能在结构体中嵌入函数
// printf("%s\n","hello world");
//}; //error!
};
void Base(){
printf("%s\n","I am Base func");
}
//struct Base base1; //ok
//Base base2; //error
int main() {
struct Base base;
base.v1=1;
//base.print();
printf("%d\n",base.v1);
Base();
return 0;
}
与C对比如下:
C++结构体中不仅可以定义数据,还可以定义函数,C++结构体中可以使用访问修饰符,如:public、protected、private,C++结构体使用可以直接使用不带struct,若结构体的名字与函数名相同,可以正常运行且正常的调用!但是定义结构体变量时候只能用带struct的。
最本质的一个区别就是默认的访问控制
默认的继承访问权限。struct 是 public 的,class 是 private 的。
struct 作为数据结构的实现体,它默认的数据访问控制是 public 的,而 class 作为对象的实现体,它默认的成员变量访问控制是 private 的。
#include<iostream>
#include<stdio.h>
struct Base {
int v1;
// private: //error!
int v3;
public: //显示声明public
int v2;
void print(){
printf("%s\n","hello world");
};
};
int main() {
struct Base base1; //ok
Base base2; //ok
Base base;
base.v1=1;
base.v3=2;
base.print();
printf("%d\n",base.v1);
printf("%d\n",base.v3);
return 0;
}
五、explicit 的用法
explicit 修饰构造函数时候,可以显示的避免隐式转换和复制初始化
#include<iostream>
using namespace std;
class Test
{
public:
Test(){cout<<"ctor()"<<endl;}
explicit Test(int i){cout<<"ctor(int)"<<endl;}
};
int main(int argc,char**argv)
{
Test test=10; //error:这里不允许隐式转换
Test test2(10); //success: 这里是规范的赋值
return 0;
}
六、enum的用法
C++11中新增了枚举类,也称作限定作用域的枚举类。
enum Color{black,white,red};
std::vector<std::size_t> primeFactors(std::size_t x); //函数返回x的质因数
Color c = red;
if(c < 14.5) //将color型别和double型别比较,发生隐式转换
{
auto factors = primeFactors(c); //计算一个color型别的质因数,发生隐式转换
}
七、decltype 的用法
decltype( expression ) 返回的是查询表达式的类型
#include <iostream>
#include <vector>
using namespace std;
/**
* 泛型编程中结合auto,用于追踪函数的返回值类型
*/
template <typename T>
auto multiply(T x, T y)->decltype(x* y)
{
return x * y;
}
int main()
{
cout << multiply(11, 2) << endl;
}
由于本人经验有限,如有错误,欢迎修正。