StringBad的构造函数和解析函数

// pass by value-程序清单 12.3 vegnews.cpp
// vegnews.cpp -- using new and delete with classes
// compile with strngbad.cpp
#include <iostream>
using std :: cout:
finclude "strngbad.h"void callmel (StringBad 6): // pass by reference
void callme2 (StringBad);int main()using std :: endl;
StringBad headlinel ("Celery Stalks at Midnight");
StringBad headline2 ("Lettuce Prey");
StringBad sports ("Spinach leaves Bowl for Dollars"):
cout << "headlinel: " << headlinel << endl;
cout << "headline2: " << headline2 << endl:
cout << "sports: " << sports << endl;
callmel (headlinel):
cout << "headlinel: " << headlinel << endl:
callme2 (headline2):
cout << "headline2: " << headline2 << endl:
cout << "Initialize one object to another: \n",
StringBad sailor - sports:
cout << "sailor: " << sailor << endl:
cout << "Assign one object to another: \n";
StringBad knot:
knot = headlinel:
cout << "knot: " << knot << endl:
cout << "End of mainlb\n"rreturn 0:382C++Primer Plus(第五版)中文版void callmel (StringBad & rsb)cout << "String passed by referencer \n":
cout << " \*" << rsb << "\"\n":-void callme2 (StringBad sb)cout << "String passed by value: \n";
cout << " \"" << sb << "\"\n";-

注意:StringBad的第一个版本有许多故意留下的缺陷,这些缺陷使得输出是不确定的。例如,有些编
译器无法编译它。虽然输出的具体内容有所差别,但基本问题和解决方法(精后将介绍)是相同的。
下面是使用Borland C++5.5命令行编译器进行编译时,该程序的输出:
1: "Celery Stalks at Midnight" object created
2: "Lettuce Prey" object created
3: "Spinach Leaves Bowl for Dollars" object created
headlinel: Celery Stalks at Midnight
headline2: Lettuce Prey
sports: Spinach Leaves Bowl for Dollars
String passed by reference:
"Celery Stalks at Midnight"
headlinel: Celery Stalks at Midnight
String passed by value:
"Lettuce Prey"
"Lettuce Prey" object deleted, 2 left
headline2: D o
Initialize one object to another:
sailor: Spinach Leaves Bowl for Dollars
Assign one objeet to another;
3: "C++" default object created
knot: Celery Stalks at Midnight
End of main()
"Celery Stalks at Midnight" object deleted. 2 left
"Spinach Leaves Bowl for Dollars" object deleted, 1 left
"Spinach Leaves Bowl for Doll8" object deleted, 0 left
"@g" object deleted, -1 left
"=|" object deleted, -2 left
输出中出现的各种非标准字符随系统而异,这些字符表明,StringBad类名副其实(是一个糟糕的类)。
另一种迹象是对象计数为负。在使用较新的编译器和操作系统的机器上运行时,该程序通常会在显示有关
还有-1个对象的信息之前中断,而有些这样的机器将报告通用保护错误(GPF)。GPF表明程序试图访问禁
止它访问的内存单元,这是另一种糟糕的信号。

程序说明
程序清单12.3中的程序开始时还是正常的,但逐渐变得异常,最终导致了灾难性结果。首先来看正常
的部分。构造函数指出自己创建了3个StringBad对象,并为这些对象进行了编号,然后程序使用重载操
作符>>列出了这些对象:
l: "Celery Stalks at Midnight" object created
2: "Lettuce Prey" object created
3: "Spinach Leaves Bowl for Dollars" object created
headlinel: Celery Stalks at Midnight
headline2: Lettuce Prey
sports: Spinach Leaves Bowl for Dollars

第12章 类和动态内存分配

然后,程序将headline1传递给cllme1()函数,并在调用后重新显示headlinel。代码如下:
callmel (headlinel) :
cout << "headlinel: " << headlinel << endl;
下面是运行结果:
String passed by reference:
"Celery Stalks at Midnight"
headlinel: Celery Stalks at Midnight
这部分代码看起来也是正常的。
但是随后程序执行了如下代码:
callme2 (headline2) :
cout << "headline2: " << headline2 << endl:
这里,callme2()按值(而不是按引用)传递headline2,结果表明这是一个严重的问题!
String passed by value:
"Lettuce Prey"
"Lettuce Prey" object deleted, 2 left
headline2: D ọ

首先,将headline2作为函数参数来传递从而导致析构函数被调用。其次,虽然按值传递可以防止原始
参数被修改,但实际上函数已使原始字符串无法识别,导致显示一些非标准字符(显示的具体内存取决于
内存中包含的内容)。
请看输出结果,在为每一个创建的对象自动调用析构函数时,情况更糟糕:
End of main ()
"Celery Stalks at Midnight" object deleted, 2 left
"Spinach Leaves Bowl for Dollars" object deleted, 1 left
"Spinach Leaves Bowl for Doll8" object deleted, 0 left
"@g" object deleted, -1 left
"-|" object deleted, -2 left
因为自动存储对象被删除的顺序与创建顺序相反,所以最先删除的3个对象是knots、sailor和sport。
删除knots和 sailor时是正常的,但在删除 sport时,Dollars变成了Doll8。对于sport,程序只使用它来初
始化sailor,但这种操作修改了sport。最后被删除的两个对象(headline2和headline1)已经无法识别。这
些字符串在被删除之前,有些操作将它们搞乱了。另外,计数也很奇怪,如何会余下-2个对象呢?
实际上,计数异常是一条线索。因为每个对象被构造和析构一次,因此调用构造函数的次数应当与析
构函数的调用次数相同。对象计数(num_strings)递减的次数比递增次数多2,这表明使用了不将 num_string
递增的构造函数创建了两个对象。类定义声明并定义了两个构造函数(这两个构造函数都使num_string递
增),但结果表明程序使用了3个构造函数。例如,请看下面的代码:
StringBad sailor = sports:
这使用的是哪个构造函数呢?不是默认构造函数,也不是参数为const char*的构造函数。记住,这种
形式的初始化等效于下面的语句:
StringBad sailor = StringBad (sports) : //constructor using sports
因为 sports的类型为StringBad,因此相应的构造函数原型应该如下:
StringBad (const StringBad &) :
当您使用…个对象来初始化另一个对象时,编译器将自动生成上述构造函数(称为复制构造函数,
因为它创建对象的一个副本)。自动生成的构造函数不知道需要更新静态变量num_string,因此会将计数
方案搞乱。实际上,这个例子说明的所有问题都是由编译器自动生成的成员函数引起的,下面介绍这一
主题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/234045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel_VBA实现:弹出对话框进行打开另存(附FileDialog 属性)

excel_vba可实现弹窗进行人机交互&#xff0c;本案例实现弹窗选择需要打开的excel文件&#xff0c;选择文件后打开该文件&#xff0c;然后弹窗提示该文件另存为路径及目录&#xff0c;代码如下&#xff1a; Sub 打开文件对话框() On Error Resume Next With Application.FileD…

【vCenter Converter】VMware vCenter Converter Standalone 理论, 下载与安装要求

目录 1. vCenter Converter 概述1.1 作用与特征&#xff08;1&#xff09;性能和可靠性&#xff08;2&#xff09;互操作性&#xff08;3&#xff09;管理 2. 下载 vCenter Converter Standalone3. 安装 vCenter Converter Standalone3.1 系统要求&#xff08;1&#xff09;支持…

邦芒支招:9个职场有效沟通技巧

在职场中&#xff0c;高效沟通是至关重要的。以下是一些建议&#xff0c;帮助你在工作职场中实现高效沟通&#xff1a; 1、明确目标&#xff1a;在开始沟通之前&#xff0c;确保你清楚自己的目标和期望结果。明确你的沟通目的&#xff0c;以便在沟通过程中保持专注和针对性。 2…

文件消失但是有占用内存的恢复方法

文件消失但占用内存是一个常见的问题&#xff0c;通常是由于文件系统错误或病毒攻击引起的。在这种情况下&#xff0c;文件虽然从目录结构中消失&#xff0c;但它们仍然占用存储空间。本文将分析这一问题的原因&#xff0c;并探讨解决该问题的几种方法。 文件消失但占用内存的原…

C++ opencv RGB三通道提升亮度

#include <iostream> #include <iomanip> #include<opencv2//opencv.hpp> using namespace std; using namespace cv; //函数adjustBrightness用于图片增加亮度 void adjustBrightness(cv::Mat& image, int targetBrightness) { // 获取图像的通道数…

android11-开机自启脚本

1. 编写myshell脚本 diff --git a/device/rockchip/rk356x/ok3568_r/myshell.sh b/device/rockchip/rk356x/ok3568_r/myshell.sh new file mode 100644 index 0000000000..c78b6d93bd --- /dev/nullb/device/rockchip/rk356x/ok3568_r/myshell.sh-0,0 1,4 #!/vendor/bin/shec…

抢先看!Salesforce Spring ‘24中的10个亮点功能!

Spring 24来临在即&#xff0c;Preview Orgs已上线。在Spring 24中&#xff0c;将会为管理员、开发人员和顾问带来更多新功能。在这片云计算的海洋里&#xff0c;一些亮点功能总能在Salesforce生态系统中引起强烈反响。本篇文章为学习者们盘点了Spring 24中的10个亮点功能&…

Vue项目搭建过程

Vue项目搭建过程 1、安装NodeJs 1.1 下载安装包 在 http://nodejs.cn/download/ 上下载64位安装包&#xff0c;然后进行安装&#xff0c;和普通软件的安装一样。 C:\Users\Administrator>node -v v16.13.1C:\Users\Administrator>npm -v 8.5.51.2 安装cnpm # 安装cn…

centos 7.x 安装docker最新版

1、查看centos版本 [rootlocalhost ~]# cat /etc/centos-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# cat /etc/os-release NAME"CentOS Linux" VERSION"7 (Core)" ID"centos" ID_LIKE"rhel fedora" VERSION_…

C语言,数组循环哪家好,指针or下标?

日常工作中&#xff0c;我们经常会用到循环遍历数组元素。不考虑只能使用某一特定方式的情况下&#xff0c;有人喜欢用数组下标遍历&#xff0c;有人则喜欢用指针遍历。那么这两者是否有性能差异呢&#xff1f; 我们先来看两个例子&#xff1a; 代码一 /* a.c */ #include &…

【QML】QML复制文件或文件夹,显示进度,多线程复制

1. 效果 可以显示复制文件和文件夹的进度 复制文件&#xff1a; bool copyFileFunc(QString _from, QString _to);复制文件夹&#xff1a;bool copyDirectoryFiles(const QString &_from, const QString &_to);举例&#xff1a; //复制文件copyhelper.copyFileToDir(&…

#HarmonyOS:Column--Row布局

Column&Row组件的使用 Column表示沿垂直方向布局的容器。 Row表示沿水平方向布局的容器。 布局子元素在交叉轴上的对齐方式 Column容器内子元素在水平方向上的排列 HorizontalAlign.Start&#xff1a;子元素在水平方向左对齐。 HorizontalAlign.Center&#xff1a;子…

推荐12款好用的在线平面设计工具,让设计更简单

平面设计是图形表达和信息展示的重要手段&#xff0c;在游戏场景和角色造型、插画、广告制作等艺术设计领域有着重要的应用&#xff0c;如海报设计、包装设计等。 平面设计强调视觉传达&#xff0c;一般以图像、图形和文字等视觉元素为主要手段&#xff0c;通过排版、配色、构…

SpringBoot、Java AOP实现方式

SpringBoot、Java AOP实现方式 搭建项目环境 我这里直接使用Maven创建项目之后再pom.xml中导入包 Spring版本 如果你的版本有最新的&#xff0c;最简单的办法就是&#xff0c;将版本都换成统一的&#xff0c;因为发布时候都是每个版本统一发布的&#xff0c;如果出现不兼容的…

大模型讲座

盘古NLP大模型典型场景 千亿大模型训练难点和解决方案 训练状态不稳定&#xff08;经常训练中断等&#xff09; 解决1&#xff1a;对loss和梯度等多维状态实时监测。对数据、学习率、参数精度、模型梯度进行针对性调整和断点恢复。 调整学习率的代码如下。调整参数、梯度类似…

浏览器缓存笔记

一、浏览器缓存中常见HTTP头部简介 1、Cache-Control响应头 public&#xff1a;表明响应可以被任何对象&#xff08;包括&#xff1a;发送请求的客户端&#xff0c;代理服务器&#xff0c;等等&#xff09;缓存&#xff0c;即使是通常不可缓存的内容。&#xff08;例如&#…

kali安装HTTrack报错Unable to locate package httrack

kali安装后&#xff0c;直接安装Httrack导致报错 Unable to locate package httrack &#xff08;这里因为解决了&#xff0c;无法重现&#xff0c;则使用错误的包httrackttttt&#xff09; 原因&#xff1a;安装kali后第一次使用系统&#xff0c;则应该运行update命令 sudo …

基于ssm省出口基地公共信息服务平台论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本n省出口基地公共信息服务平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞…

算法训练营Day19

#Java #二叉树 #双指针 开源学习资料 Feeling and experiences&#xff1a; 二叉搜索树的最小绝对差&#xff1a;力扣题目链接 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的…

eNSP小实验--实现全网互通

目录 一、建立以下拓扑图&#xff0c;并实现全网互通 二、分析 1、接入层交换机SW4、SW5划分vlan 2、汇聚层交换机SW2,SW3配置ip作为vlan网关&#xff0c;与SW1直连 3、核心交换机SW1配置ip 与汇聚层交换机和R1直连 4、SW1,SW2,SW3,R1配置静态路由&#xff0c;使得vlan10,…