• c++ 02


    一、堆内存的动态分配与释放
    malloc/calloc/realloc/free
    new/delete:详见memory.cpp
    1.通过new运算符分配单个变量
    数据类型* 指针变量 = new 数据类型(初值);
    2.通过new运算符分配数组
    数据类型* 指针变量 = new 数据类型[数组长度] {元素初值, ...};
    3.对于单个变量用delete销毁,而对于数组用delete[]销毁
    4.定位分配
    数据类型* 指针变量 = new(起始地址) 数据类型(初值);
    起始地址所标记的内存应该事先分配好。
    5.new在分配内存(malloc)之后还会调用构造函数,delete/delete[]在释放内存(free)之前先调用析构函数。

    二、引用
    1.引用即别名
    int a = 10;
    int& r = a; // r是a的一个别名
    r = 20;
    cout << a << endl; // ? 20
    2.引用必须初始化
    int& r; // ERROR !
    3.引用一旦初始化,就不能再引用其它变量
    int a = 10;
    int& r = a;
    int b = 20;
    r = b; // b -> a
    4.引用型参数和返回值
    void foo (int a) { a = 100; }
    void bar (int* a) { *a = 100; }
    void hum (int& a) { a = 100; }
    void print (const int& a) {
      cout << a;
      a = 100; // ERROR !
      ++a; // ERROR !
    }
    int b = 0;
    foo (b); // b : 0
    bar (&b); // b : 100
    hum (b); // b : 100
    print (b);
    1)希望在函数中修改实参的值。
    2)避免值传递所带来的开销。
    3)为了防止在函数中意外地修改实参的值,可以使用const型的引用。
    int* a (char);
    int (*a) (char);
    int (*a[5]) (char);
    4)const型的引用可以接受具有const属性的实参。
    5)引用型返回值常用于实现从函数返回左值的场合。
    6)不可以从函数中返回局部变量的引用,就如同不可以从函数中返回指向局部变量的指针一样。可以返回全局变量、静态变量、成员变量、引用型参数本身、堆变量的引用。
    5.引用和指针
    1)引用的本质就是指针,引用不是实体变量。
    2)指针可以不初始化,但是引用必须初始化。
    int a;
    int* p;
    p = &a;
    int& r = a;
    3)指针的目标可以修改,但是引用的目标不可修改。
    int a, b;
    int* p = &a;
    p = &b;
    int& r = a;
    4)可以定义指向指针的指针,但是不能定义引用引用的引用。
    int* p;
    int** pp = &p;
    int& r = a;
    int&& rr = r; // ERROR !
    5)可以定义引用指针的引用,但是不能定义指向引用的指针。
    int* p;
    int*& rp = p;
    int a;
    int& r = a;
    int&* pr = &r; // ERROR !
    6)可以定义指针数组,但是不能定义引用数组。可以定义数组引用。
    int a, b, c;
    int* parr[] = {&a, &b, &c};
    int& rarr[] = {a, b, c}; // ERROR !
    int arr[] = {1, 2, 3};
    int (&arrr)[3] = arr;

    三、显示类型转换
    C:目标类型变量 = (目标类型)源类型变量;
    int n;
    char c;
    c = (char)n;
    C++:五种转换形式
    1.C风格的另一种写法
    目标类型变量 = 目标类型 (源类型变量);
    int n;
    char c;
    c = char (n);
    2.静态类型转换:static_cast<目标类型>
    int n;
    char c;
    c = static_cast<char> (n);
    在源类型和目标类型之间至少在一个方向上可以隐式转换。
    1)类型的相容性
    double/char*
    int* pn;
    void* pv = pn;
    int* pi = static_cast<int*> (pv);
    2)自定义类型转换(单参构造、类型转换操作符)
    3.动态类型转换:dynamic_cast<目标类型>
    应用具有多态性的父子类的指针或引用之间。
    4.常量类型转换:const_cast<目标类型>
    去除常量型指针或者引用的常属性。
    int a = 10;
    const int* p = &a;
    *p = 20; // ERROR !
    int* q = p; // ERROR !
    int* q = const_cast<int*> (p); // 去常
    const int b = 10;
    b = 20; // ERROR !
    b++; // ERROR !
    5.重解释类型转换:reinterpret_cast<目标类型>
    应用于在不相关的指针或者引用之间,以及指针和整数之间,进行类型转换。
    struct Student { ... };
    Student s = { ... };
    char* p = reinterpret_cast<char*> (&s);
    int n = reinterpret_cast<int> (p);

    四、C++之父的建议
    1.在C++中尽量不用宏,代之以const、enum或inline。
    #define PAI 3.1415926
    const double PAI = 3.1415936;
    #define ERROR_FILE -1
    #define ERROR_MEM  -2
    enum ERROR {
      ERROR_FILE = -1,
      ERROR_MEM  = -2
    };
    2.变量随用随声明。
    3.少用malloc/calloc/free,代之以new/delete。
    4.少用void*、指针算术、联合、强制类型转换。
    5.少用C风格的字符串,进行使用string类型。
    6.有意识地使用面向对象的思想。
    面向过程/基于对象(BOP)/面向对象(OOP)

  • 相关阅读:
    ASP.Net 反射显示
    ASP.Net 反射简单工厂模式
    ASP.Net MVC生成验证码
    ASP.Net EF架构
    ASP.Net 邮箱发送
    ASP.Net 反射简单
    ASP.Net 显示
    新年快乐
    测试开发比
    Linkbot介绍
  • 原文地址:https://www.cnblogs.com/elisha-blogs/p/3780673.html
Copyright © 2020-2023  润新知