第12章 类和动态内存分配

  1、不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存。可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的组成部分。注意:静态成员在类声明中声明,在包含类方法的文件中初始化。初始化时使用作用域操作符来指出静态成员所属的类。但如果静态成员是整型或枚举型const,则可以在类声明中初始化。

  2、当使用一个对象来初始化另一个新建对象时,编译器将自动生成一个复制构造函数,因为它创建对象的一个副本。复制构造函数的原型为:classname(const classname &);

  3、C++自动提供了下面的这些函数:①默认构造函数,如果没有定义构造函数②复制构造函数,如果没有定义③赋值操作符,如果没有定义④默认析构函数,如果没有定义⑤地址操作符,如果没有定义

  4、何时调用复制构造函数:新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。例如,假设motto是一个stringbad类对象,则下面4种声明都将调用复制构造函数:

  ①stringbad ditto(motto);②stringbad metto=motto;③stringbad also=stringbad(motto);④stringbad *p=new stringbad(motto);其中②③可能会使用复制构造函数直接创建metto和also,也可能使用复制构造函数生成一个临时对象,然后将临时对象的内容赋给metto和also,这取决于具体的实现。

  5、每当程序生成了对象副本时,编译器都将使用复制构造函数。具体地说,当函数按值传递(创建原始变量的一个副本)或函数返回对象时,都将使用复制构造函数。编译器生成临时对象时,也将使用复制构造函数。

  6、默认的复制构造函数逐个复制非静态构造函数(浅复制),复制的是成员的值。如果成员本身就是类对象,则将使用这个类的复制构造函数来复制成员函数。静态函数不受影响。

  7、如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这也称为深度复制。浅复制也叫成员复制,只是复制指针值,而不会深入挖掘来复制指针引用的结构。

  8、赋值操作符:C++允许类对象赋值,这是通过自动为类重载赋值操作符实现的。这种操作符的原型如下:

  classname & classname::operator=(const classname &);

  9、何时使用赋值操作符:将已有的对象赋给另一个对象时,将使用重载的赋值操作符。注:初始化(创建新对象)总是会调用复制构造函数,而使用=操作符也可能调用赋值操作符。赋值操作符并不创建新的对象。

  10、与复制构造函数相似,赋值操作符的隐式实现也对成员进行逐个复制(浅复制)。如果成员本身就是类对象,则程序将使用为这个类定义的赋值操作符来复制该成员。对于由于默认赋值操作符不合适导致的问题,解决方法是提供赋值操作符(进行深度复制)定义。其实现与复制构造函数相似,但也有一些差别。一个例子:

  stringbad & stringbad::operator= (const stringbad & st)

  {

    if(this==&st)  // 检查自我复制

      return *this;

    delete [] str;  // 释放成员指针以前指向的内存

    len=st.len;

    str=new char[len+1];

    std::strcpy(str,st.str);

    return *this;    // 返回一个指向调用对象的引用

  }

  11、由于静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。

  12、重载>>操作符:

  istream & operator>>(istream & is,string & st)

  {

    char temp[10];  // 假设输入的字符数不多于10

    is.get(temp,10);  // 如果由于某种原因(如到达文件尾,或读取的是一个空行),导致输入失败,istream对象的值将置为false

    if(is)

      st=temp;

    while(is&&is.get()!='\n')  // 丢弃多余的字符

      continue;

    return is;

  }

  13、if(!cin)检测空行!!

  14、可以在一个构造函数中使用new来初始化指针,而在另外一个构造函数中将指针初始化为空(NULL或0),这是因为delete(无论带中括号还是不带)可以用于空指针。

  15、如果函数返回传递给他的对象,可以通过传递引用来提高方法的效率。返回对象将调用复制构造函数,而返回引用不会。

  16、重载操作符<<函数,返回类型必须是ostream &,而不能仅仅是ostream。如果返回类型ostream,将要求调用ostream类的复制构造函数,而ostream没有公有的复制构造函数。

  17、总结:如果方法或函数返回局部对象,则应返回对象而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。如果方法或函数返回一个没有公有复制构造函数(如ostream类)的对象,它必须返回一个指向这种对象的引用。最后,有些方法和函数(如重载的赋值操作符)可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率高。

  18、成员初始化列表:classname::classname(int n,int m):mem1(n),men2(0),men3(n*m+2){ //....}从概念上说,这些初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码。对于简单数据成员,使用成员初始化列表和在函数体中使用赋值没有什么区别。不过,对于本身就是类对象的成员来说,使用成员初始化 列表效率更高。注:①这种格式只能用于构造函数。②必须用这种格式初始化非静态const数据成员。③必须用这种格式初始化引用数据成员。

  19、在类中嵌套结构和类声明: 在类声明中声明的结构、类或枚举被称为是被嵌套在类中,其作用域为整个类。这种声明不会创建数据对象,而只是指定了可以在类中使用的类型。如果声明是在类的私有部分进行的,则只能在这个类中使用被声明的类型;如果声明是在公有部分进行的,则可以从类的外部通过作用域解析操作符使用被声明的类型。例如:如果Node是在Queue类的公有部分声明的,则可以在类的外面声明Queue::Node类型的变量。

转载于:https://www.cnblogs.com/smile233/p/8931865.html

《C++ Primer Plus》读书笔记之十—类和动态内存分配相关推荐

  1. C++ Primer Plus学习(十一)——类和动态内存分配

    类和动态内存分配 动态内存和类 静态类成员 特殊成员函数 string类的改进 构造函数中的new 返回对象 指向对象的指针 成员初始化列表(member initializer list) 动态内存 ...

  2. C++类与动态内存分配

    11.10 类与动态内存分配 通常,最好是在程序运行时(而不是编译时)确定诸如使用多少内存等问题.对于在对象中存储姓名来说,通常的C++方法是,在类构造函数中使用new运算符在程序运行时分配所需的内存 ...

  3. 第12章类和动态内存分配

    第12章类和动态内存分配 (1) class student {char name[40];//并不是每一个字符串都是40//如果是一个对象数组,则浪费空间 }; 12.1 (1)静态成员在类声明中声 ...

  4. 读书笔记||类和动态内存分配

    一.动态内存和类 C++在分配内存的时候是让程序是在运行时决定内存分配,而不是在编译时再决定.C++使用new和delete运算符来动态控制内存.但是在类中使用这些运算符将导致许多新的编程问题,在这种 ...

  5. 第12章-cpp类和动态内存分配

    本章内容包括: • 对类成员使用动态内存分配. • 隐式和显式复制构造函数. • 隐式和显式重载赋值运算符. • 在构造函数中使用new所必须完成的工作. • 使用静态类成员. • 将定位new运算符 ...

  6. C++ 学习笔记之---类和动态内存分配

    参考自<C++ Primer Plus 6th Edition> 程序对内存的使用: 链接:http://zhidao.baidu.com/link?url=An7QXTHSZF7zN9r ...

  7. 读书笔记——Java虚拟机垃圾收集器与内存分配策略

    本文章已授权微信公众号郭霖(guolin_blog)转载. 本文章讲解的内容是Java虚拟机垃圾收集器与内存分配策略. 概述 说起垃圾收集(Garbage Collection),也就是GC,大部分人 ...

  8. 深入理解JVM读书笔记二: 垃圾收集器与内存分配策略

    3.2对象已死吗? 3.2.1 引用计数法 给对象添加一个引用计数器,每当有一个地方引用它的地方,计数器值+1:当引用失效,计数器值就减1;任何时候计数器为0,对象就不可能再被引用了. 它很难解决对象 ...

  9. 类和动态内存分配——C++ Prime Plus CH12

    ①动态内存和类 1.复习示例和静态类成员 使用程序复习new和delete用法. // badstring.h文件 #include<iostream> #ifndef STRING_BA ...

最新文章

  1. 30. SQL -- 完整性及约束(1)
  2. row间距 table 某一行_UITableview的一个section下的各行Row之间可以设置间隔一段距离吗?...
  3. 当输入 xxxxHub 后,到网页显示,其间发生了什么?
  4. WPF-21:WPF实现仿安卓的图案密码键盘(初级)
  5. 视频列表页html,视频列表.html
  6. Linux 14.04 CUDA theano安装
  7. mapbox绘制航线图
  8. 哈佛幸福课 24人格力量测试
  9. python捕捉warning_Pytest官方教程-10-捕获警告信息
  10. windows下安装使用Nide
  11. 计算机组成和导论,计算机科学导论五第章计算机组成
  12. 安装最新版本zlib
  13. 机器学习之线性回归模型的代价函数是凸函数的证明
  14. ZZULIOJ1086: ASCII码排序(多实例测试)
  15. Linux基础 第三节 第三课
  16. 减肥服务APP开发详细内容
  17. C# 解压压缩包及 7z 库缺失导致 Can not load 7-zip library or internal COM error!
  18. JVM优化,以及垃圾回收的相关面试题请注意查收!
  19. 【引用】ubuntu服务器配置-(二)
  20. mysql计算时间差(时/分/秒)函数

热门文章

  1. java中如何使用jdk_java – 如何在JDK7中使用目录globbing
  2. c语言 字节 半字 字,PLC的位,半字节,字节,字介绍
  3. 返回值带头信息 php_php与Redis实现分布式锁
  4. 学python编程好就业吗_学好python编程就业真的没有压力吗?
  5. php后端接收数据,后端如何接收fetch方式发送的数据?
  6. 关于 try catch 捕捉不到异常
  7. Node.js路径操作
  8. php 精度比较,PHP浮点数精度和比较
  9. 中国计量学院全国计算机二级报名,中国计量大学教务管理系统入口https://jwc.cjlu.edu.cn/...
  10. linux neo4j weget,关于在linux中安装neo4j的步骤