动态内存分配小记



  • 类和动态内存分配

    • 静态类成员:无论创建了多少对象,程序都只创建一个静态类变量副本,即类的所有对象共享同一个静态成员

      。要注意,不能在类声明中初始化静态类成员变量,因声明只是描述如何分配内存,但并不分配内存.注意初始化是在是在方法文件中而不是类声明文件,而且要使用作用域运算符来指出静态成员所属的类。例外:静态数据成员为const整数类型或枚举型。

    • 警告:在构造函数中使用new来分配内存时,必须在析构函数中使用delete来释放内存

    • 析构函数将在定义对象的代码块执行完毕时调用

    • c++自动提供下述成员函数:

      • 默认构造函数,若没有定义构造函数
      • 默认析构函数,若没有定义
      • 复制构造函数,若没有定义
      • 赋值运算符,若没有定义
      • 地址运算符,若没有定义
    • 复制构造函数:新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。具体地说,当函数按值传递对象或函数返回对象时

    • c++11空指针:引入新关键字nullptr,str=nullptr
      
    • 静态类成员函数:

      (1)不能通过对象调用静态类成员函数,实际上静态成员函数甚至不能使用this指针。若其在共有部分声明,则可以使用类名和作用域解析运算符来调用它。

      (2)由于它不与特定函数关联,因此只能使用静态数据成员

    • 在构造函数中使用new应注意:
      (1)若构造函数中使用new来初始化指针成员,则应在析构函数中delete
      (2)new与delete必须互相兼容
      (3)如有多个构造函数,则必须以相同的方式new,要么都带中括号,要么都不带
      (4)应定义一个复制构造函数,通过深度复制将一个对象初始化为另一个对象
      String::String(const String&st)
      {
          num_string++;
          len = st.len();
          str = new char [len+1];
          std::strcpy(str, st.str);
      }
      复制构造函数应分配足够的空间来存储复制的数据,并复制数据,二不仅仅是数据的地址。另外,还应更新所有受影响的静态类成员。
      (5)应定义一个赋值运算符,通过深度复制将一个对象复制给另一个对象
      String & String::operator=(const String&st)
      {
          if(this == &st)
              return *this;
         	delete [] str;
          len = st.len;
          str = new char [len+1];
          std::strcpy(str, st.str);
          return *this;
      }
      //具体说,应:检查自我赋值的情况,释放成员指针以前指向的内存,复制数据而不仅仅是数据的地址,并返回一个指向调用对象的引用
      
    • 如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用

    • 析构函数何时被调用:

      • 如果对象是动态变量,则当执行完定义该对象的代码块时,将调用该对象的析构函数
      • 如果对象是静态变量(外部,静态,静态外部或来自名称空间),则在程序结束时将调用对象的析构函数
      • 如果对象是new创建的,则仅当显示使用delete删除对象时,其析构函数才会被调用
    • 使用对象指针时,要注意:

      • 使用常规表示法来声明指向对象的指针:String * a;
      • 可以将指针初始化为指向已有的对象
      • 可以使用new来初始化指针,这将创建一个新对象
      • 对类使用new将调用相应的类构造函数来初始化新创建的对象
      • 可以使用->运算符通过指针访问类方法
      • 可以对对象指针*来获得对象
    • 再谈定位new运算符:

      • 程序员必须负责管用定位new运算符用从中使用的缓冲区内存单元。要使用不同的内存单元,程序员需要提供两个位于缓冲区的不同地址,并确保这2个内存单元不重叠。
      • 如果使用定位new运算符来为对象分配内存,必须确保其析构函数被调用。
    • 嵌套结构和类:在类中声明的结构,类和枚举被称为嵌套在类中,作用域为整个类。这种声明不会创建数据对象,只是指定了可以在类中使用的类型。若声明在private,则只能在这个类使用;在public则可从类外部通过::来声明。

    • c++11的类内初始化:
      class Classy
      {
          int mem = 10;
          const int mem2 = 20;
      }
      上述代码与 Classy::Classy():mem(10),mem2(20) {...} 等价
      

 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待