switch
int main() {
switch (3) {
case 0:
// 报错,初始化可能被跳过
int a = 3;
break;
case 1:
// 不报错,没有初始化
int b;
// 报错,初始化可能被跳过
std::string c;
break;
case 2: {
// 不报错,定义为局部变量
int d = 4;
// 不报错,定义为局部变量
std::string e;
}
break;
case 3:
b = 4;
std::cout << b << std::endl;
break;
default:
break;
}
return system("pause");
}
nullptr
代码
void fun(int i) {
std::cout << "fun(int i)" << std::endl;
}
void fun(char * c) {
std::cout << "fun(char * c)" << std::endl;
}
int main() {
fun(NULL);
fun(nullptr);
return system("pause");
}
示例
fun(int i)
fun(char * c)
引用折叠
-
X & &
, X & &&
, X && &
都折叠成类型X &。
-
X && &&
折叠成X &&
。
decltype
int main() {
int i1 = 0; // int
decltype(i1) i2; // int
auto & i3 = i1; // int
decltype(i3) i4 = i1; // int &
int * i5; // int *
decltype(i5) i6; // int *
decltype(*i5) i7 = i1; // int &
return system("pause");
}
标准类型转换模板
// 标准类型转换模板参考表
typedef int T; // T代指其他类型
int main() {
int i0 = 0;
std::remove_reference<int &>::type i1; // int
std::remove_reference<int &&>::type i2; // int
std::remove_reference<T>::type i3; // T
std::add_const<int &>::type i4 = i0; // int &
std::add_const<const int>::type i5 = i0; // const int
std::add_const<T>::type i6 = i0; // const T
std::add_lvalue_reference<int &>::type i7 = i0; // int &
std::add_lvalue_reference<int &&>::type i8 = i0; // int &
std::add_lvalue_reference<T>::type i9 = i0; // T &
std::add_rvalue_reference<int &>::type i10 = i0; // int &
std::add_rvalue_reference<int &&>::type i11 = 0; // int &&
std::add_rvalue_reference<T>::type i12 = 0; // T &&
std::remove_pointer<int * >::type i13; // int
std::remove_pointer<T>::type i14; // T
std::add_pointer<int &>::type i15; // int *
std::add_pointer<int &&>::type i16; // int *
std::add_pointer<T>::type i17; // T *
std::make_signed<unsigned int>::type i18; // int
std::make_signed<T>::type i19; // T
std::make_unsigned<int>::type i20; // unsigned int
std::make_unsigned<T>::type i21; // T
std::remove_extent<int[10]>::type i22; // int
std::remove_extent<T>::type i23; // T
std::remove_all_extents<int[10][10][10]>::type i24; // int
std::remove_all_extents<T>::type i25; // T
return system("pause");
}
remove_reference与decltype的应用
// std::move()的实现是std::remove_reference的应用
template <typename T>
typename std::remove_reference<T>::type && fakeMove(T && t) {
return static_cast<typename std::remove_reference<T>::type &&>(t);
}
int main() {
int i1 = 0; // int
auto & i2 = i1; // int
auto && i3 = i1; // int
std::remove_reference<decltype(i2)>::type i4; // int
std::remove_reference<decltype(i3)>::type i5; // int
std::remove_reference<int &>::type i6; // int
return system("pause");
}
未定义行为
int a[10];
int i = 0;
a[i++] = i; // 未定义行为
a[++i] = i; // 未定义行为
枚举类型C++11新特性
enum MyEnum { A, B, C };
MyEnum fun() {
return MyEnum::A;
}
constexpr
constexpr int * i1 = nullptr; // i1是个常量
const int * i2 = nullptr; // *i2是个常量
fstream
- 使用fstream会在离开作用域的时候自动销毁,不需要调用close成员函数,是异常安全的。而fopen以后不会离开作用域也不会调用fclose,是非异常安全的。
enum
- enum枚举体分为不限定作用域enum和C++11的限定作用域enum。
enum Global1 {
A = 1
};
// 发生重定义错误:A重定义了
//enum Global2 {
// A = 2
//};
// C++11写法:不会发生重定义错误
enum class Local {
A = 3
};
int main() {
std::cout << static_cast<int>(A) << std::endl;
std::cout << static_cast<int>(Local::A) << std::endl;
return system("pause");
}
其他
- 用const修饰的对象具有内部链接,相当于static,只有本文件可见。
- 字符字面值是
char
类型,字符串字面值是const char *
类型。函数可以返回字符串字面值,但是返回值类型必须是const char *
-
std::cin
读入char
类型字符时也会跳过空白字符。
- 数组最大大小是
std::size_t
值,数组中的两个元素距离是std::ptrdiff_t
值。
-
while((ch = getchar()) != EOF)
中,这句代码有以下值得注意的地方:
- getchar()的返回值为int类型。
- 某些机器中char的取值范围可能是-127至128、0至255二者之一。
- 若getchar()返回EOF(通常是-1)且char的取值范围是0至255,则EOF会溢出变为255,无限循环。
- 如果漏掉内部的括号,会导致getchar()先与EOF进行比较,接着把比较结果赋给ch。
- 头文件不能进行相互包含,如果两个类相互依赖,可以使用前向声明,或反思设计。
网友评论