C++ Day13-其他语法 B 类型转换 lambda表达式

299 阅读1分钟
1. C 语言中的类型转换有哪两种?C++ 中的类型转换有哪四种?
  • C 语言: (type)expression、type(expression)
  • C++: static_cast、dynamic_cast、reinterpret_cast、const_cast
  • C++使用格式: xxx_cast(expression)
  • 类型转换的本质(仔细品):强制类型转换大部分时候是在欺骗编译器,让代码编译通过
2. const_cast
  • 一般用于去除 const 属性,将 const 转换成非 const
const Person *p1 = new Person();
cout << p1->m_age << endl; // 输出 0
//p1->m_age = 10; // 会报错

//Person *p2 = (Person *)p1;
Person *p2 = const_cast<Person *>(p1);
/*
上面两句类型转换代码生成的汇编代码完全一致,都是如下汇编,所以说类型转换其实是在欺骗编译器
0x100003f6c <+60>: movq   -0x10(%rbp), %rdx
0x100003f70 <+64>: movq   %rdx, -0x18(%rbp)
*/
p2->m_age = 20;

cout << p1->m_age << endl;// 输出 20
cout << p2->m_age << endl;// 输出 20
3. dynamic_cast
  • 一般用于多态类型的转换,有运行时安全检测
  • 运行父类指针指向子类实例,不允许子类指针指向父类实例
Person *p1 = new Person();
Person *p2 = new Student();


cout << "p1 - " << p1 << endl; // p1 - 0x1007660e0
cout << "p2 - " << p2 << endl; // p2 - 0x100764a90

Student *stu1 = dynamic_cast<Student*>(p1);
Student *stu2 = dynamic_cast<Student*>(p2);

cout << "stu1 - " << stu1 << endl; // stu1 - 0x0
cout << "stu2 - " << stu2 << endl; // stu2 - 0x100764a90
4. static_cast(了解即可)
  • 对比 dynamic_cast , 缺乏运行时安全检测
  • 不能交叉转换(不是同一继承体系的,无法转换)
  • 用于基本数据类型转换,非 const 转成 const
5. reinterpret_cast
  • 属于比较底层的强制转换,没有任何类型检查和格式转换,仅仅是简单的二进制数据拷贝
  • 可以交叉转换
  • 可以将指针和整数相互转换
Person *p1 = new Person();
Person *p2 = new Student();


cout << "p1 - " << p1 << endl; // p1 - 0x1007660e0
cout << "p2 - " << p2 << endl; // p2 - 0x100764a90

Student *stu1 = reinterpret_cast<Student*>(p1);
Student *stu2 = reinterpret_cast<Student*>(p2);
stu1->m_age = 20;
stu2->m_age = 21;

cout << "stu1 - " << stu1 << " m_age - " << stu1->m_age << endl; // stu1 - 0x100593370 m_age - 20
cout << "stu2 - " << stu2 << " m_age - " << stu2->m_age << endl; // stu2 - 0x100591b60 m_age - 21


int i = 10;
double d1 = reinterpret_cast<double &>(i);
cout << "i - " << &i << "  d1 - " << &d1 << endl; // i - 0x7ffeefbff414  d1 - 0x7ffeefbff408
cout << "d1 - " << d1 << endl; // d1 - 5.23561e-307
6. 计算机中浮点数的存储分为哪三段数据?
  • 从左到右:符号位、指数位、尾数部分
  • - 5.23561e-307 经典的浮点数表示法
7. auto 关键字的作用?auto 会影响程序的运行效率吗?
  • auto 可以从初始化表达式中推断出变量的类型,大大简化了编程工作
  • auto 属于编译器特性(可能会影响编译效率);不影响最终的机器码质量,不影响运行效率
8. nullptr 对比 NULL 有特别作用?
  • nullptr 专门用于表示空指针,可以解决 NULL 的二义性问题,而 NULL 可以表达任何为空的数据
9. C++ lambda 表达式格式如何?本质是什么?
  • C++ 中的 lambda 表达式本质是 函数

image.png

10. 一些 lambda 表达式的经典写法?
int main() {
    
    // 1. 一个定义之后直接调用的 lambda 表达式
    ([] {
        cout << "lambda1()-------" << endl;
    })();
    
    // 2. 因为 lambda 表示是一个函数,用指针可以指向
    void (*p2)() = [] {
        cout << "lambda2()-------" << endl;
    };
    p2();
    
    // 3. 带参数和带返回值的 lambda
    int (*sum)(int, int) = [] (int a, int b) -> int {
        return a + b;
    };
    cout<< sum(1, 2) << endl; // 输出 3
    
    // 4. 值捕获(指定捕获)的 lambda
    int a = 10;
    int b = 0;
    auto p4 = [a]() {
        cout << "lambda4()-------" << a << endl;
    };
    a = 14;
    p4(); // 输出:lambda4()-------10
    
    // 5. 值捕获(用到的都捕获)的 lambda
    auto p5 = [=]() {
        cout << "lambda4()-------" << a << " b: " << b << endl;
    };
    a = 15;
    p5(); // lambda4()-------14 b: 0
    
    // 6. 引用捕获(指定捕获)的 lambda
    auto p6 = [&a]() {
        cout << "lambda4()-------" << a << endl;
    };
    a = 16;
    p6(); // lambda4()-------16
    
    // 7. 引用捕获(用到的都捕获)的 lambda
    auto p7 = [&]() {
        cout << "lambda4()-------" << a << " b: " << b << endl;
    };
    a = 17;
    b = 27;
    p7(); // lambda4()-------17 b: 27
    
}