C++ Primer Plus(十二)——类和动态内存分配

烂漫一生 提交于 2019-12-01 12:12:06
  1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化。初始化时使用作用域运算符来指出静态成员所属的类。但如果静态成员是整型或枚举型const,则可以在类声明中初始化。

  2. strlen返回字符串长度,但不含末尾的空字符

  3. 字符串并不保存在对象中,而是单独保存在堆内存中,对象仅保存了到哪去查找字符串的信息。

  4. 删除对象可以释放对象本身占用的内存,但不能自动删释放属于对象成员的指针所指向的内存,所以必须使用析构函数并用delete释放这种内存。

  5. 按值传递、生成临时对象时,都将调用复制构造函数。

  6. 如果类中包含了使用new初始化的指针成员,则应当定义一个复制构造函数,以复制指向的数据,而不是指针,这类称为深度复制,复制的另一种形式是调用隐式复制构造函数,进行浅复制,浅复制仅仅复制指针信息,而不会深入挖掘以复制指针引用的结构。

  7. 与复制构造函数相似,赋值运算符的隐式实现也对成员进行逐个复制。

  8. 复制构造函数和赋值构造函数的重新定义上的区别:

    1. 由于目标对象可能引用了以前分配的数据,所以函数应用delete[ ] 来释放这些数据

    2. 函数应当避免将对象赋给自身;否则给对象重新赋值前,释放内存操作可能删除对象的内容

    3. 函数返回一个指向调用对象的引用

  9. delete[ ] 与使用new[ ]初始化指针和空指针都兼容,对于以其他方式初始化的指针,使用delete[  ]时,结果将是不确定的,如new char[1]与 new char分配的内存量相同,区别在于前者与delete[ ]兼容,而后者不兼容

  10. C++98中,字面值0既可以表示数字0,也可以表示空指针,也有程序员使用NULL;在C++11中,引入新关键字nullptr,建议使用它来表示空指针

  11. 较早的get(char*,int)版本在读取空行时,第一个字符将是空字符;而较新的版本里返回值为false,采用

    if (!cin || temp[0] == '\0' ) break;

    则if语句中的第一个条件将检测到空行,第二个条件用于旧版本检测到空

  12. 如果有多个构造函数,必须以相同的方式使用new,要么带中括号,要么都不带。因为只有一个析构函数,所有的构造函数的都必须与他兼容。

  13. 应定义一个复制构造函数,通过深度复制将一个对象初始化为另一个对象,即应分配足够的空间来存储复制的数据,并复制数据,而不仅仅是数据的地址,并更新受影响的静态类成员。

  14. 应定义一个赋值运算符,通过深度复制将一个对象复制给另一个对象,该方法应该完成这些操作:检查自我赋值的情况,释放指针以前指向的内存,复制数据而不仅仅是数据的地址,并返回一个指向调用对象的引用。

  15. 如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。如果方法或函数要返回一个没有公有复制构造函数的类的对象,则必须返回一个指向这种对象的引用。最后有些方法和函数可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。

  16. 如果对象是动态变量,则当执行完该对象的程序块时,将调用该对象的析构函数

  17. 如果对象是静态变量,则在程序结束时将调用对象的析构函数

  18. 如果对象是new创建的,则仅当显示使用delete删除对象时,其析构函数才会被调用

  19. 定位new运算符能够在分配内存时指定内存位置,但无法使用delete运算符。要对定位new运算符使用的内存单元进行管理,必须加入合适的delete和显式的析构函数调用:对于定位new运算符创建的对象,应以与创建顺序相反的顺序予以删除(晚创建的对象可能依赖于早创建的对象),另外仅当所有对象都被销毁后,才能释放用于存储这些对象的缓冲区。

  20. 如果数据成员是非const成员或引用,则必须采用这种格式,但可将C++11新增的类内初始化用于非静态const成员。

  21. C++允许类内初始化,这与使用成员初始化列表等价,然而使用成员初始化列表的构造函数将覆盖相应的类内初始化。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!