《C++ Primer 》第四十九天 在实践中学习新知识

对类中的成员 使用动态内存分配

复制构造函数(有隐式 和 显式 两种方法)

类 在程序运行时分配内存 ,可 通过在 类的构造函数中使用 new运算符 —— 这样就可以在程序运行时 进行内存分配(例如,string 类 就通过这种方式,实现了 在运行时进行内存分配。string 类 提供的接口 是非常有好的——这其中 就涉及了大量的编程技术)

在类中使用 new运算符时,就必须定义 析构函数——用来 释放内存。(在类中使用new运算符时,除了要定义析构函数,有时 还需要 重载赋值运算符——用来保证程序的正常运行。)

类 中的静态成员变量 不在类声明中进行初始化——而是 在类声明代码块之外 使用单独的语句进行初始化(静态成员的初始化语句 不应在类声明文件中——而是 在 类成员函数定义 的那个文件中,对 类的 静态成员进行初始化。这是因为 类声明 代码块 是在 头文件中——头文件 可能会被多个文件包含,如果 对 静态成员进行初始化的语句 也在头文件中,就有可能 出现 对同一个静态成员进行多次初始化,这样会引发错误。但是也有一种情况 是可以在类中 对静态成员进行初始化——就是当 类的 静态成员 为整型或 const枚举型 时 可以 在类声明中直接对 类的静态成员进行初始化。) ——并且初始化语句 不需要 使用 static关键字,例如 int StringBad::num_strings=0;。(这是因为 ,类中 的静态成员 是单独存储的——不是单个对象的组成部分)

strlen() 函数 返回字符串(不包括末尾的空字符)的长度

类的构造函数 使用new分配的内存,是属于一块独立的内存(堆——和 类的对象 所在的内存是分开的)。

删除类的对象 能够释放 对象本身 所占的内存,但并不能自动释放 对象 中的 成员(指针) 指向的内存(也就是 构造函数中new出来的内存),因此 必须在析构函数中 使用 delete语句 来释放 之前在构造函数中 用new分配得到的内存。(如果 动态分配内存的时候 使用的是 new [] 这种语法,那么释放该内存的时候 应该使用 delete [] 这种语法来释放内存。例如 分配内存:str=new char[len+1];  释放内存:delete [] str;)

当创建一个 新对象 并且 有其他对象对其进行初始化的时候(这时,初始化该对象 所使用的构造 函数 不是 自己定义的构造函数 也不是 系统默认的构造函数,而是 由编译器 自动生成的一个构造函数——叫做复制构造函数。这个复制构造函数的函数原型为:StringBad(const StringBad &);)

类中 C++默认提供的 成员函数 有:默认构造函——在没有定义构造函数的情况下提供(默认构造函数的定义为:Klunk::Klunk(){}),默认析构函数——在没有定义析构函数的情况下提供,复制构造函数——在没有定义复制构造函数的情况下提供(一般,当 使用 一个对象  对另一个对象初始化的时候会  调用该函数;当程序 生成对象副本的时候,也会调用该函数——比如 当函数 按值传递对象时 或者 当函数 返回对象时 都会 调用 复制构造函数;还有就是 当编译器生成临时对象时 也会调用 复制构造函数),赋值运算符——在没有对赋值运算符进行重载的情况下提供(一般是 将一个对象 赋值 给 另一个对象的时候 才会自自动冲对赋值运算符进行重载——重载赋值运算符 的 函数原型 为 StringBad & StringBad::operator=(const StringBad &);  重载实现的这个赋值运算符 返回的是 一个 指向 类对象 的引用),地址运算符——在没有对地址运算符进行重载的情况下提供(一般是 返回对象的地址的时候 会自动生成)。(除此之外 C++11 还提供了 另外两个 特殊的成员函数:移动构造函数 和 移动赋值运算函数)

由于 按值 传递对象 会调用 复制构造函数,所以 一般应该选用 按引用传递 对象——这样不会 调用复制构造函数,同时减少程序的开销

对于 new 分配的内存 ,如果 只复制  指向这块内存的指针——这被称为浅复制;如果 开辟一块新的内存,并在这块新的内存中,生成 new分配的内存中的 数据 的副本,然后 生成一个 指向 副本内存的指针 ——这叫做深复制

默认的复制构造函数——主要功能是 复制 非静态成员(这里复制的是 非静态成员的值(如果又 指向 new分配的内存的 指针成员,那么对该成员采用的是 浅复制)。并且 复制构造函数 不会对 静态成员进行复制,因为静态车成员 属于整个类 而不是只属于单个对象)

StirngBad  knot; knot=headline1;(这两条语句,虽然用到了 赋值运算符,但实际上是 创建了一个对象并 使用另一个对象对其进行初始化,这会调用复制构造函数——但不一定会 重载 复制运算符。并且 自动重载的复制运算符  和 自动生成的 复制构造函数 功能类似,都是 对 类对象的 非静态成员进行 浅拷贝)

如果将一个指针的值置0,那么就相当于将这个指针设置为空指针。(0有两个含义,一个是  数值0, 另一个 是可以表示 空指针——空指针还有其其他形式:如使用(void *)0 来表示空指针、使用 C语言 中的 宏 NULL 来表示空指针、C++11中引入了 关键字 nullptr 来表示空指针——str= nullptr,这样 str就被设置为 空指针。例如 str=0,那么str 就是变成了空指针。空指针 也可以使用  delete[] 这种语法 来对其进行内存释放——本质上不会做任何操作。)

delete 只能用于 使用 new函数返回的指针 和 空指针 (用于释放 指针所指向的内存空间)

在进行函数重载(或运算符重载的时候),带cosnt关键字  和 不带const 关键字 的函数 算是两种函数,编译器是可以区分的——因此 进行函数重载的时候,可以重载两个具有相同参数列表的函数——但是必须是 一个是添加 const关键字 一个是不添加const关键字

静态成员函数  属于整个类 不属于单个对象,因此静态成员函数  只能通过 类名::函数名()的方式 进行调用,不能通过 对象名或者 this 指针 来进行调用。(并且静态成员函数 只能访问静态成员变量,不能访问 非静态成员变量)

空指针有多重表示方法:0、NULL、C++11中 使用  nullptr  来表示空指针

空字符 用 ‘\0’ 来表示。

如果一个函数 最终 返回的是 对象,那么该函数返回对象的时候会调用 复制构造函数;如果一个函数 最终 返回的是对象的引用,那么返回结果的时候 就不会调用 复制构造函数。

ostream 类 没有公有 的复制构造函数(所以,一般 当此类的对象作为函数的返回结果的时候,函数返回 此类对象的引用 ——这样就不需要调用复制构造函数)。(也就是说 如果  函数 要放回一个 类的对象 ,但是该类 没有 公有的 复制构造函数,那么该函数只能返回 一个 指向 该对象的 引用)

使用new 来 创建(可能会便随着初始化)的对象,当时用 delete 对象  这种语法 删除对象的时候,会调用对象的析构函数 。其他类别的对象,是在这些对象销毁的时候,才。会调用 这些对象的析构函数(比如 如果对象是  静态变量,该变量 是在程序结束的时候自动销毁——也就是说在程序结束的时候,才会调用这些变量的析构函数。对于非静态变量,那么它们是在执行完 它们所在的代码块的时候 会自动销毁——也就是说 当他们 所在的代码块执行完毕的时候,会调用这些变量的析构函数)

通过指针访问 类中的成员函数 的 语法是:int s=point -> length();

对于 使用 定位new 运算符创建的对象,使用 delete释放内存的时候,并不会自动调用对象的析构函数——因此 对于 使用 定位new运算符创建的对象,必须显示的调用 该对象的析构函数(语法为:p->~JustTesting();)。(因此 对于  定位new运算符创建的对象,的正确的删除和释放内存的方式是:首先按照  和创建顺序想法的顺序  依次的调用对象的析构函数——来销毁所有对象,例如,p2->~JustTesting();p1->~JustTesting();;当所有对象都被销毁之后,然后使用 delete语句来释放内存——比如,delete [] buffer;)

一个类 只能有一个析构函数 但是可以有多个 构造函数——因此 如果涉及到 使用 new来分配内存,这些构造函数  都要 和 这一个 析构函数对应(也就是说, 如果析构函数中 用的 是 delete[]语句来对内存进行释放,那么所有的构造函数中都必须使用 new[] 这种语句来分配内存;如果 析构函数中 用的 是 delete 语句来释放内存 ,那么所有的构造函数中必须 使用 new 这种 语句来分配内存)

C++ 的类 中 可以嵌套 其他类或结构——这些  在类1中 嵌套的 类2或结构 的作用域是 这个类1,也就是说,即使 类1外面 有和 类1内 一模一样定义的 类2或结构,也不会发生冲突。(有一些 老的 编译器 不支持 这种 类中 再嵌套 类或结构)

当调用类的构造函数 创建对象时,对象 将在 构造函数 中的代码执行之前 进行创建——也就是说 会首先 给对象中的成员变量 分配内存,之后 在执行 构造函数代码的时候,才将 具体的值 赋给每个成员(也就是 将具体的值 放到相应的内存中)。(也就是说 如果对象中含有 const成员,那么该成员 在构造函数的代码执行前 就已经被创建了——因此不能 在构造函数中 对其更改。针对 对象中的const成员,C++提供了一种 语法(成员初始化类表)来 在 const成员创建的时候进行初始化。成员初始化类表的语法为:Queue::Queue(int qs):qsize(qs) { ; ;}。   这种语法不仅可用于初始化 const成员 ,也可以用于初始化任何 其他 对象成员,例如 Queue::Queue(int qs):qsize(qs),front(NULL),rear(NULL),items(0) {; ; ;} 。 只有构造函数才可以使用 成员初始化列表 这种语法,并且 对于 对象 中的 const 成员 和 引用类型的成员 必须通过 这种语法进行初始化——因为 const成员 和  引用类型的成员  都只能在创建的时候进行初始化;其他成员则 可以不用这种语法进行初始化;并且 当使用 成员初始化列表 的时候,列表中 对象成员 的初始化顺序 和 类声明中的顺序一致——而不是 按照 成员初始化列表中 书写的顺序)

如果 类 的构造函数中 使用了new来分配内存 ,那么 该类 中一般要 对 复制构造函数进行定义 和 赋值元素符进行重载——以实现 深复制。(同样  实现 队列的 类 也需要实现 深复制。并且如果将 上面提到的  两个 成员函数 设置为  private——实现的效果 就是 不允许 进行 类的 负值,也就是说 不允许 使用 该 类的对象 初始化 其他的 该类对象 ,也不允许 将 该类的对象 赋值给 其他的 该类对象 )

可以将两个类 合并到一个文件中——也就是说 ,将两个类声明文件 合并成一个 文件 ;将 两个类 的 成员函数定义文件  合并为 一个 文件。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355