深入学习C++关键字

alignas&alignof
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

struct Foo {
int a;
char c;
float f;
};

struct Empty{};

struct alignas(64) Empty64 {};
//0会被忽略
struct alignas(0) BB {};

struct alignas(8) Double {
double d;
};

struct Obj {
char a;
int b;
};

//alignof
int s_obj = sizeof(Obj); //8
int a_obj = alignof(Obj); //4

void alignInfo() {
std::cout << "Alignment of" "\n"
"- char :" << alignof(char) << "\n" //1
"- pointer :" << alignof(int*) << "\n" //8 4
"- empty class :" << alignof(Empty) << "\n" //1
"- class Foo :" << alignof(Foo) << "\n" //4
"- alignas(64) Empty :" << alignof(Empty64) << "\n" //64
"- alignas(1) Double :" << alignof(Double) << "\n"; //8(WIN下编译报错)
}
and&&and_eq
1
2
3
4
5
6
7
8
9
#include <iso646.h>
void AND() {
//and 等价于 &
int a = 10;
int b = 20;
b and_eq a;
//等价于 b &= a;
//等价于 b = b & a;
}
asm

用于在C++代码中嵌入汇编语言,不常用

auto
  1. 对于变量,指定将要从其初始值设定项自动推断出要声明的变量的类型。

  2. 对于函数,指定将其从其return语句推导返回类型。

  3. 对于非类型模板参数,指定将从参数推导类型。

bitand&bitor
1
2
3
4
5
6
void showBitAndor() {
auto a = 3L;
auto b = 4;
auto c = a bitand b; //等价于 &
auto d = a bitor b; //等价于 |
}
constexpr
1
2
3
4
5
//运行时计算
int fact(int n) { return n <= 1 ? 1 : (n * fact( n - 1)); }

//编译时计算
constexpr int factorial(int n) { return n <= 1 ? 1 : (n * factorial( n - 1)); }

constexpr所修饰的变量一定是编译期可求值的,所修饰的函数在所有的参数都是constexpr时,一定会返回constexpr。

constexpr的好处:

  1. 是一种很强的约束,更好的保证程序的正确语义不被破坏。
  2. 编译期可以在编译期对constexpr的代码进行非常大的优化,比如将用到的constexpr表达式都直接替换成最终结果等。
  3. 相对于宏来说,没有额外的开销,更安全可靠。
const_cast
1
2
3
4
5
6
void testConstCast(){
const int j = 3; //j is declared const
//const int*
int* pj = const_cast<int*>(&j);
*pj = 4; //undefined behavior!
}

const_cast一般不推荐使用,出现的时候大多数意味着代码结构出现了问题,const本身表示不可变的,const_cast转换 却破坏了这个不变性。

decltype

用于获取变量或者表达式的类型或者函数的返回类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
struct A { double x;};
void testDecl(){
const A* a = new A{ 0 };
auto aa = a->x;
decltype(a->x) y; //double
auto& cc = y;
decltype((a->x)) z = y; //double&
}

template<typename T, typename U>
//后置函数类型
auto add(T a, U b) -> decltype(a+b){
return a+b;
}

/*
error cant compile
decltype(a+b) add(T a, U b){
return a+b;
}
*/


void testDecltype(){
auto cc = add(1,3); //cc int
auto dd = add(1.0, 3); //dd double
}
dynamic_cast

沿继承层级向上、向下及侧向,安全地转换 到其他类的指针和引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct Base{virtual ~Base(){}};

struct Derived : Base {
virtual void name(){}
};

void TestDyn(){
Base *b1 = new Base;
if(Derived *d = dynamic_cast<Derived*>(b1)){ //fail
std::cout << "downcast from b1 to d successful\n";
d->name(); //safe to call
}

Base *b2 = new Derived;
if(Derived *d = dynamic_cast<Derived *>(b2)){ //success
std::cout << "downcast from b2 to d successful\n";
d->name(); //safe to call
}

Base bb;
//fail throw bad_cast exception
//Derived& cc = dynamic_cast<Derived&>(bb);

delete b1;
delete b2;
}

本文标题:深入学习C++关键字

文章作者:Tokey

发布时间:2020年03月12日 - 11:03

最后更新:2021年06月29日 - 22:06

原始链接:http://TokeyRoad.github.io/2020/03/12/C++关键字-1/

许可协议: 转载请保留原文链接及作者。

0%