《C++ Primer Plus》读书笔记之十—类和动态内存分配
第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类型的变量。
《C++ Primer Plus》读书笔记之十—类和动态内存分配的更多相关文章
- 《C++ Primer Plus》第12章 类和动态内存分配 学习笔记
本章介绍了定义和使用类的许多重要方面.其中的一些方面是非常微妙甚至很难理解的概念.如果其中的某些概念对于您来说过于复杂,也不用害怕——这些问题对于大多数C++的初学者来说都是很难的.通常,对于诸如复制 ...
- C++ primer plus读书笔记——第12章 类和动态内存分配
第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...
- C++_类和动态内存分配3-构造函数中使用new的注意事项
如果在构造函数中使用new来初始化对象的指针成员时必须特别小心. 1 如果在构造函数中使用new来初始化指针成员,则应在析构函数中使用delete. 2 new和delete必须相互兼容.new对应于 ...
- 深入理解Java虚拟机读书笔记2----垃圾收集器与内存分配策略
二 垃圾收集器与内存分配策略 1 JVM中哪些内存需要回收? JVM垃圾回收主要关注的是Java堆和方法区这两个区域:而程序计数器.虚拟机栈.本地方法栈这3个区域随线程而生,随线程而灭,随着方 ...
- C++——类和动态内存分配
一.动态内存和类 1.静态类成员 (1)静态类成员的特点 无论创建多少对象,程序都只创建一个静态类变量副本.也就是说,类的所有对象都共享同一个静态成员. (2)初始化静态成员变量 1)不能在类声明中初 ...
- C++ Primer Plus读书笔记(十)对象和类
1.类 不废话,上定义 class ClassName { public: xxx; private: xxx; protected: xxx; } private部分数据只能通过public 提供的 ...
- C primer plus 读书笔记第十四章
这一章主要介绍C语言的结构和其他数据形式,是学习算法和数据结构的重点. 1.示例代码 /*book.c -- 仅包含一本书的图书目录*/ #include <stdio.h> #defin ...
- C primer plus 读书笔记第十二章
C的强大功能之一在于它允许我们控制程序的细节.C的内存管理系统正是这种控制能力的例子.它通过让我们决定哪些函数知道哪些变量以及一个变量在程序中存在多长时间来实现这些控制. 1.存储类及其说明符 主要的 ...
- 《C++ Primer Plus》12.6 复习各种(类和动态内存分配的)技术 笔记
12.6.1 重载<<运算符要重新定义<<运算符,以便将它和cout一起用来显示对象的内容,请定义下面的友元运算符函数:ostream & operator<&l ...
随机推荐
- lua闭包与简易迭代器实现
1.什么是闭包 闭包,又称闭合函数(closure).通常,如果将一个函数写在另一个函数内,那么这个在内部的函数就可以访问到外部函数中的局部变量,这个特征就是词法域,有些资料上也叫它词法定界.闭包指的 ...
- Golang cron 定时任务使用
1.cron 表达式的基本格式 用过 linux 的应该对 cron 有所了解.linux 中可以通过 crontab -e 来配置定时任务.不过,linux 中的 cron 只能精确到分钟.而我们这 ...
- yum安装 指定安装目录
yum -c /etc/yum.conf --installroot=/usr/local --releasever=/ install love
- SpringBean 工作原理详解
本文来自Github开源项目https://github.com/Snailclimb/JavaGuide,只供自己学习总结无商业用途,如有侵权,联系删除 前言 在 Spring 中,那些组成应用程序 ...
- Nginx面试
声明:此文章非本人所 原创,是别人分享所得,如有知道原作者是谁可以联系本人,如有转载请加上此段话 1.请解释一下什么是 Nginx? Nginx是一个 web服务器和反向代理服务器,用于 HTTP.H ...
- 【学习笔记】--- 老男孩学Python,day12 函数名的应用,闭包,迭代器
1, 函数名的应用,第一类对象 函数名可以像变量一样进行使用 1.赋值 def func(): print("你吃了么?") # print(func) # a = func # ...
- 关于android R.layout 中找不到已存在的布局文件问题的解决
今天遇到一个很奇怪的问题,打R.layout.,居然不会提示已经写好的布局文件,自己把xml文件名打下去后,居然提示错误. 开始以为是R文件中没有自动生成关于布局文件对应的整型,看了R文件,其实是有生 ...
- js-NodeList对象和HTMLCollection对象
getElementsByName()和getElementsByTagName()都返回NodeList对象,而类似document.images和document.forms的属性为HTMLCol ...
- js dictionary字典 遍历
var dic={A:"AA",B:"BB",C:"CC"} //不能length去for循环(length:undefined) dic[ ...
- opencv3.2.0形态学滤波之膨胀
//名称:膨胀 //日期:12月21日 //平台:QT5.7.1+opencv3.2.0 /* 膨胀(dilate)的含义: 膨胀就是求局部最大值的操作,就是将图像(或图像的一部分,A)与核 B 进行 ...