• c++(一) :从c到c++


    以下内容是c++中,大多是c没有的或与c不同的语言特性。

    bool类型

    值取true和false.

    const 常量标识符

    //const int a;  // error,常量必须初始化
    const int a = 100;
    // a = 200;    // error,不能对常量赋值

    const int * p // 定义了一个指向常量的指针变量(*p是常量)
    int * const p2 = &a; // p2是常量,需初始化

    /* const常量与#define定义的符号常量的区别
    * 1.const定义的常量有类型,而#define定义的没有类型,编译可以对前者进行安全检查,对后者只是 * 做简单替换
    * 2.const常量在编译时分配内存,#define定义的在预编译进行替换,不分配内存
    * 3.作用范围不同,前者作用域为变量的作用域,后者从定义点到程序结束(也可用#undef取消)
    */

    // 尽量用const、enum代替#define

    内存对齐

    • 是什么:1.编译器为每个“数据单元”安排在某个合适的位置上. 2.c,c++允许干涉内存对齐
    • 为什么:在对齐的内存空间上能更快的访问数据
    • 怎么用:

    域运算符::

    // 用法1:对与局部变量同名的全局变量进行访问
    #include <iostream>
    using namespace std;
    
    int var = 100;
    int main()
    {
        int var = 50;
        cout << var <<endl;   // 50
        cout << ::var << endl; // 100
    }

     new与delete

    • 是操作符,不是函数
    • new用于创建堆空间,成功返回首地址, 用法:
    • delete 释放堆空间
      // new:分配内存,调用构造函数
      int *p;
      p = new int;
      char *p_str = new char[50];
      
      // delete:调用析构函数,释放内存
      delete [] p_str;
      delete p;

    重载

    函数名相同,参数不同(数量,类型,顺序)

    引用

    • 就是给一个变量起别名(引用不是变量,只是变量的别名)
      int a = 100;
      int &b = a; // b是a的别名
      b = 200;
      cout << b <<" " << a << endl; // 200 200
    • 引用没有自己的空间
    • 对引用的改变相当于对原变量的改变
    • 用法:
      // 1.作为函数参数
      void swap(int &a, int &b)
      {
          int tmp = a;
          a = b;
          b = tmp;
      }

      // 2.引用作为返回值,主要目的是可以将函数放在赋值运算符的左边(不能返回对局部变量的引用)
      #include <iosteam>
      using namespace std;

      int a[] = {0, 1, 2, 3, 4};
      int& index(int i)
      {
      return a[i];
      }
      int main()
      {
      index(3) = 100;   // 引用作为函数返回值,使得函数可以放在赋值运算符左边
      // 函数返回引用,引用在函数返回的时候初始化
      cout << a[3] << endl; // 100
         return 0;
      }

     引用与指针的区别

    1. 引用访问变量是直接访问,指针是间接访问
    2. 引用没有自己的内存空间,指针有
    3. 引用初始化后不能再引用其他变量,指针可以

    (c++中尽可能使用引用)

     内联函数

    1.背景

    首先来看函数调用的过程:

      建立占空间->保护现场->传递参数->控制程序执行的转移->...

    对于一些本身功能简单,代码简短,使用频率很高的函数,频繁调用会严重影响程序效率,可以通过将代码嵌入程序中,但这样又会产生大量重,为了解决效率与重复的矛盾,c++提供了一种方法——内联函数(定义函数时使用 inline 修饰).

    内联函数是在编译的时候展开的(相当于嵌入到代码中,不存在函数调用).

    2.内联函数与带参数宏的区别

    • 内联函数要求实参形参类型一致,先对实参表达式求值,然后传递给形参;而宏调用时只用形参进行简单的替换.
    • 内联函数在编译时使用、在调用的地方将代码展开;宏调用在预编译时进行替换

    新的类型转换

    旧式:

      (T)expr

    新式:

    1. const_cast<T>(expr)
      // 移除对象的常量性
      // 一般用于指针或者引用
      // 去除const限定不是为了修改它的内容
      // 通常是为了函数能接受这个参数
      #include <iostream>

      void fun(int &val)
      {
        cout << "test" << endl;  
      }
      using namespace std; int main() { const int val = 100; // int n = const_cast<int> (val); // error,不能用于对象 int n = val; // int *p = &val; error,无法从const int * 转换为int * int *p = const_cast<int*>(&val); *p = 200; cout << val << endl; // 100,并未改变,产生临时对象



      const int val2 = 200;
      // int& ref2 = val2; 非const引用不能指向const对象
      int& ref2 = const_cast<int&>(val2);
      ref2 = 300;
      cout << val2 << " " << ref2 << endl; // 200 300

        // func 函数要求传入非const引用,这时可以用const_cast对val2进行转换
      fun(const_cast<int&>(val2)) return 0; }
    2. static_cast<T>(expr)
      1. 编译器的隐式转换:编译器自动转换,一般来说是安全的,比如说int a; short b; a = b; 编译器隐式执行的任何类型转换都可以有static_cast完成;
      2. 当一个较大的算术类型赋值给较小的类型时,可以使用static_cast进行强制转换,例:
        // double -> int
        #include <iostream> using namespace std; int main() { int n = static_cast<int>(3.14); cout << n << endl; // 3 return 0; }
      3. 可以将void*指针转换为某一类型的指针;

      4. 可以将基类指针转成派生类指针
      5. 无法将const转换为nonconst
    3. reinterpret_cast<T>(expr)
      /*
       * reinterpret_cast:将数据以二进制存在形式的重新解释
       */
      int i;
      char *p = "This is a example.";
      i = reinterpret_cast<int>(p);
      // 此时结果,i与p完全相同
      
      
      int *ip;
      char *pc = reinterpret_cast<char *>(ip);
      // 需要记得pc所指向的真实对象是int型,并非字符串。
      // 如果将pc当作字符指针进行操作,可能会造成运行时错误
      // 如int len = strlen(pc);
    4. dynamic_cast<T>(expr): 只接受基于类对象的指针或引用的类转换

    尽可能避免转换,若无法避免使用新式类型转换

  • 相关阅读:
    VS2013 添加 ILDasm
    XmlIgnore的使用
    前端常见跨域解决方案(全)
    网络请求中的cookie与set-Cookie的交互模式的一些问题解析
    各浏览器Cookie大小、个数限制
    Linux常用命令分类
    给博客园中博文的图片添加单击时弹出放大效果——lightbox
    给博客园中博文的图片添加单击时弹出放大效果—— zoom.js
    CSS3新单位vw、vh、vmin、vmax使用详解
    session,cookie,sessionStorage,localStorage的相关设置以及获取删除
  • 原文地址:https://www.cnblogs.com/ezhengnan/p/3661944.html
Copyright © 2020-2023  润新知