1. 头文件: 新版本以c开头,并省略.h,比如: #include <cstdio>
2.头文件尽量使用#ifdef/#ifndef...#else...#endif,防止重复引用头文件
3.命名空间不要过度使用,如果使用的函数不是很多的情况,可以使用: using xxx指定此函数,比如: using std::cout
4.
a.命名空间c++17之前
namespace A{
namespace B {
namespace C{
...
}
}
};
而c++17简化成: namespace A:B:C{
...
};
b.命名空间可以使用别名:
namespace myABC = A::B::C;
5. 变量申明的时候最好赋初始值,否则很容易引起bug
6.如果某个运算中包含多个运算符,不了一目了然,最好使用括号将表达式分成若干个小表达式
7. 建议枚举使用安全强类型 enum class, 例如: enum class eColorType{
red,
green,
blue
};
这样编译器就不会自动将枚举转化为整形, 如果使用if(eColorType::red == 0),此处会报错;
8.switch不能允许的类型:
浮点型:精度问题
字符串:可有需要strcmp等函数来比较
9. c++14以后允许函数使用auto自动推导出返回类型,如果参数有多个,那么需要保证各个参数类型统一
例如:
template <typename T>
auto GetSum(const T& a , const T& b)
{
return (a + b);
}
10. 数组的初始方式
例如: 方法一:int nArr[3]; nArr[0] = 0;nArr[1] = 0;nArr[2] = 0;
方法二: int nArr[3] = {0};
方法三: int nArr[3] = {};
方法四: int nArr1[3]{0};
11. c++17中 std::size(nArr) 求的是数组的个数,类似于旧版的sizeof(nArr)/sizeof(nArr[0])
12. 可以使用auto绑定结构体,且绑定时的变量个数一定要与结构体实际变量个数一致
例如: struct myStruct
{
int nX;
double dY;
float fZ;
};
myStruct mS;
mS.nX = 1;
mS.dY = 2.0;
mS.fZ = 3.0f;
auto[x, y, z] = mS;
cout <<"x = " << x << " y = " << y <<" z = " << z << endl; // x = 1 y = 2 z = 3
13. c++提供了四种循环结构:
while:只有条件为真时才会执行
do..while:会保证至少执行一次
for(int i = 0; i < 10; i++)...
和基于区间的for循环: for(auto i : 迭代器)...
14. 初始化列表initializer_list,函数接受一个列表
示例:
template <typename T>
auto GetSum(const std::initializer_list<T> &lst)
{
T tRet = NULL;
for (auto i : lst)
{
tRet += i;
}
return tRet;
}
std::initializer_list<int> lst = {1, 2, 3};
cout << GetSum(lst) << endl; //6
cout << GetSum({4.0, 5.0, 6.0}) << endl; //15
15. 尽量避免使用c分格的malloc和free动态分配和删除内存,可以使用new/delete或者 new[]/delete[]
16. NULL和nullptr区别,nullptr用于指针的判断或者初始
17. 智能制造 unique_ptr
//使用方法:
auto atEmployee= std::make_unique<Employee>();
//如果编译器不支持c++14,则可以使用以下方法声明:
unique_ptr<Employee> upEmployee (new Employee);
//如果要声明智能指针数据:
auto atEmployerr = std::make_unique<Employee>[]>(10);
//而share_ptr如果要声明数组,只能在c++17中使用,且只能是旧版本的声明方式
std::shared_ptr<Employee[]> spEmployee(new Employee[10]);
18.如果要给函数传递参数,最好使用const加引用,如果函数需要修改对象,则传递非const引用,减少对象复制
19. try{} catch(std::exceptiion e){}
20. auto会创建副本,所以去除引用和const限定,如果不需要副本,可以使用auto &或者 const auto &
21. decltype可以推导出类型
例如:
int x = 10;
decltype(x) y = 20;
22. c++11之前结构体初始化使用{}, 类初始化使用();
而在c++11之后都可以使用{}初始化
myStruct ms = {10, 20, 30};//myStruct ms{10, 20, 30};
myClass mc(10,20,30); // myClass mc = {10, 20, 30};//myClass mc{10, 20, 30};
同理常用类型初始也一样:
int a = 0; int a(0); int a {0}; int a = {0};
23. 字符串结束符\0要占一个字节
const char *pS = "hello";
int nSize = strlen(pS);//这里要加1,否则有问题
char *pBuf = new char[nSize];
memset(pBuf, 0, nSize);
strcpy_s(pBuf, nSize, pS);
cout << pBuf << endl;
24.字符串常量保存在常量区,属于只读
const char *pStr = "hello"; //只读,如果试图修改,会报错
char chArr[] = "hello"; //这里chArr在栈上,拷贝了一份"hello"副本,可以修改
25.字符串字面量,表示方法: R"(内容)"
示例: const char *path = R"(C:\test.txt)";
注意: 内容中不要出现制表符,\t, \n等等
如果字符串中需要)"等特殊符号,则需要使用: R"任意标识(内容)任意标识"
const char *pStr = R"-(Embedded)" characters)-";
26, std::string用法
c_str(),遇到\0就结束,返回的是const char*;
data(),从c++17开始,返回的是char*;
auto s1 = "hello";
cout << typeid(s1).name() << endl; // const char *
auto s2 = "hello"s; //注意这里s,用户字面量
cout << typeid(s2).name() << endl; //std::string
to_string() //可以将各种数据类型转换成std::string
stoi, stol,stod,stof,stoll,stoul...//可以将std::string转化为各种数据类型
27. std::string_view
可以代替 const std::string &, const char*
可以通过data()转换为std::string
auto s = "hello"sv; //可以通过字面常量sv,将字符串显示为std::string_view
28. 命名统一,做到顾名思义
29.尽量用引用代替指针
30.c++设计两大原则: 抽象和重用
31.数组在做为参数的时候为什么会退化成指针
主要是为了提高效率,如果数组占用内存大,这样做可以避免数据内存的拷贝
32.
持续更新...