C++_第八周做题总结

id:45 A.Equation(类与对象+构造)

题目描述

建立一个类Equation,表达方程ax2+bx+c=0。类中至少包含以下方法:

  1. 无参构造(abc默认值为1.0、1.0、0)与有参构造函数,用于初始化a、b、c的值;

  2. set方法,用于修改a、b、c的值

  3. getRoot方法,求出方程的根。

一元二次方程的求根公式如下:
在这里插入图片描述
一元二次方程的求解分三种情况,如下:
在这里插入图片描述

输入

输入测试数据的组数t

第一组a、b、c

第二组a、b、c

输出

输出方程的根,结果到小数点后2位

在C++中,输出指定精度的参考代码如下:

#include <iostream>
#include <iomanip> //必须包含这个头文件
using namespace std;void main( )
{double a =3.14;cout<<fixed<<setprecision(3)<<a<<endl;  //输出小数点后3位

输入样例

3
2 4 2
2 2 2
2 8 2

输出样例

x1=x2=-1.00
x1=-0.50+0.87i x2=-0.50-0.87i
x1=-0.27 x2=-3.73

题解

  • 首先分析类,Equation();,无参构造,用于初始化abc的值;void set(double m, double n, double p);,用于将abc的值修改为参数的值;void getRoot();求根的函数,在函数中,我们首先定义一个变量来记录b * b - 4 * a * c的值,然后通过这个值的判断,分为三种情况进行讨论,注意,当这个变量小于零时,我们开平方时需要开这个变量的相反数,最后做一些细节处理输入输出即可
  • 在主函数中,我们输入abc的值后,调用设置值的函数,将输入的值传递到类的变量中,然后进行x值的输出

代码实现

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;class Equation
{
private:double a, b, c;
public:Equation(); // 无参构造,初始化void set(double m, double n, double p); // 修改a, b, c的值void getRoot(); // 求根
};Equation::Equation()
{a = 1.0;b = 1.0;c = 0;
}void Equation::set(double m, double n, double p)
{a = m;b = n;c = p;
}void Equation::getRoot()
{double x1, x2, t, j1, k1, k2;t = b * b - 4 * a * c;if (t == 0){x1 = (-b + sqrt(t)) / (2 * a);cout << "x1=x2=" << fixed << setprecision(2) << x1 << endl;}else if (t > 0){x1 = (-b + sqrt(t)) / (2 * a);x2 = (-b - sqrt(t)) / (2 * a);cout << "x1=" << fixed << setprecision(2) << x1 << " x2=" << fixed << setprecision(2) << x2 << endl;}else // 共轭复数{j1 = -b / (2 * a);k1 = (sqrt(-t)) / (2 * a);k2 = (sqrt(-t)) / (2 * a);cout << "x1=" << fixed << setprecision(2) << j1 << "+" << fixed << setprecision(2) << k1;cout << "i x2=" << fixed << setprecision(2) << j1 << "-" << fixed << setprecision(2) << k2 << "i" << endl;}
}int main()
{int t, i;double aa, bb, cc;Equation y;cin >> t;for (i = 0; i < t; i++){cin >> aa >> bb >> cc;y.set(aa, bb, cc);y.getRoot();}return 0;
}

id:50 B.对象是怎样构造的(拷贝构造函数)

题目描述

某个类包含一个整型数据成员.程序运行时若输入0表示用缺省方式定义一个类对象;输入1及一个整数表示用带一个参数的构造函数构造一个类对象;输入2及一个整数表示构造2个类对象,一个用输入的参数构造,另一个用前一个对象构造。试完成该类的定义和实现。

输入

测试数据的组数 t

第一组数

第二组数

输出

第一个对象构造输出

第二个对象构造输出

输入样例

3
0
1 10
2 20

输出样例

Constructed by default, value = 0
Constructed using one argument constructor, value = 10
Constructed using one argument constructor, value = 20
Constructed using copy constructor, value = 20

题解

  • 首先来分析类,Member(); // 缺省定义,用于初始化val的值;Member(int a);用于将参数的值赋值到valMember(const Member&ans1); // 拷贝构造函数,我们也是将参数的val值赋值到val中;void set(int b); // 设置值,用于将参数的值赋值到val中;int get(); // 获得值,返回val的值
  • 在主函数中,输入组数后,在for循环中在输入一个整数表示用什么方法来构造,然后通过这个整数的判断,用不同的方法,然后不同的输出

代码实现

#include <iostream>
using namespace std;class Member
{
private:int val;
public:Member(); // 缺省定义Member(int a);Member(const Member&ans1); // 拷贝构造函数void set(int b); // 设置值int get(); // 获得值
};Member::Member()
{val = 0;
}Member::Member(int a)
{val = a;
}Member::Member(const Member&ans1)
{val = ans1.val;
}void Member::set(int b)
{val = b;
}int Member::get()
{return val;
}int main()
{int t, i, n, x;cin >> t;for (i = 0; i < t; i++){cin >> n;if (n == 0){Member ans;cout << "Constructed by default, value = " << ans.get() << endl;}else if (n == 1){cin >> x;Member ans(x);cout << "Constructed using one argument constructor, value = " << ans.get() << endl;}else if (n == 2){cin >> x;Member ans1(x); // 输入的参数构造cout << "Constructed using one argument constructor, value = " << ans1.get() << endl;Member ans2(ans1); // 调用拷贝构造函数cout << "Constructed using copy constructor, value = " << ans2.get() << endl;}}return 0;
}

id:51 C.电话号码升位(拷贝构造函数)

题目描述

定义一个电话号码类CTelNumber,包含1个字符指针数据成员,以及构造、析构、打印及拷贝构造函数。

字符指针是用于动态创建一个字符数组,然后保存外来输入的电话号码

构造函数的功能是为对象设置键盘输入的7位电话号码,

拷贝构造函数的功能是用原来7位号码的对象升位为8位号码对象,也就是说拷贝构造的对象是源对象的升级.电话升位的规则是原2、3、4开头的电话号码前面加8,原5、6、7、8开头的前面加2。

注意:电话号码只能全部是数字字符,且与上述情况不符的输入均为非法

输入

测试数据的组数 t

第一个7位号码

第二个7位号码

输出

第一个号码升位后的号码

第二个号码升位后的号码

如果号码升级不成功,则输出报错信息,具体看示例

输入样例1

3
6545889
3335656
565655

输出样例1

26545889
83335656
Illegal phone number

输入样例2

2
1234567
22a2567

输出样例2

Illegal phone number
Illegal phone number

题解

  • CTelNumber类:先定义一个私有的字符型指针,用于存储号码;四个公有的函数,CTelNumber(char *p1); // 构造,构造函数,用于设置七位电话号码;~CTelNumber(); // 析构,析构函数,用于释放动态创建的用于存储电话号码的字符指针所指向的空间;void print(); // 打印,打印函数,用于打印电话号码;CTelNumber(const CTelNumber& p1); // 拷贝构造,是拷贝构造函数,用于处理在电话号码前添加数字
  • CTelNumber(char *p1);,构造函数,我们先用srelen函数计算得到传入的电话号码的字节数,然后为phone申请的内存空间比得到的字节数多2,一个用来存储后面添加进来的数字,一个用来放字符串结束符\0,然后使用strncpy函数将值进行赋值,最后在末尾放结束标志符
  • CTelNumber(const CTelNumber& p1);拷贝构造函数,首先为phone申请一段新的内存空间,然后赋值,判断号码的第一位的数字是几,则实行不同的相应操作,操作结束后在字符数组的末尾添加字符串结束符
  • 首先读入组数,然后我们是用字符数组存储电话号码,所以我们要去掉输入组数后的那个换行符,然后动态创建一个字符指针,输入号码,获取长度,判断其长度是否为7,若不是,则视为非法输入,否则,挨个判断每个元素是否是数字,若不是,记为非法输入,所以我们需要有一个变量判断输入进来的电话号码是否为非法输入,还要判断电话号码的第一位数字不能是019,若输入的号码是正确的,则进行构造初始化,和拷贝构造在开头新添数字,然后输出,最后记得要释放动态创建的内存

犯的错误

修改前的代码中

  1. CTelNumber 构造函数中,我首先为 phone 分配了新的内存,然后立即将 phone 指向 p1。这样会导致内存泄漏,因为我无法再访问和删除之前分配的内存。所以应该使用 strncpy 函数来复制 p1phone

  2. 在拷贝构造函数中,我没有为 phone 分配新的内存,但是试图将数据复制到 phone。这将导致未定义的行为,因为我正在写入未分配的内存。所以需要首先为 phone 分配新的内存。

  3. 我之前的的程序没有处理电话号码的长度。如果电话号码的长度不是7,程序可能会出现问题。所以需要添加一些检查来确保电话号码的长度是正确的。

  4. 且我在判断输入的电话号码是否合法时,及判断输入的第一位数字,没有用到ACSLL的值

代码实现

#include <iostream>
#include <cstring>
using namespace std;class CTelNumber
{
private:char* phone;
public:CTelNumber(char *p1); // 构造~CTelNumber(); // 析构void print(); // 打印CTelNumber(const CTelNumber& p1); // 拷贝构造
};CTelNumber::CTelNumber(char *p1) // 设置7位电话号码
{size_t len = strlen(p1);phone = new char[len + 2]; // 存储'\0'strncpy(phone, p1, len);phone[len] = '\0';
}CTelNumber::~CTelNumber()
{delete[] phone;
}void CTelNumber::print()
{cout << phone << endl;
}CTelNumber::CTelNumber(const CTelNumber& p1)
{int i, len;len = strlen(p1.phone);phone = new char[len + 2]; // 重新分配内存,存储'\0'strncpy(phone, p1.phone, len);if (*phone == '2' || *phone == '3' || *phone == '4') // 234开头{*phone = '8';for (i = 0; i < 7; i++){*(phone + 1 + i) = *(p1.phone + i);}}else{*phone = '2';for (i = 0; i < 7; i++){*(phone + 1 + i) = *(p1.phone + i);}}*(phone + len + 1) = '\0'; // 添加结束字符
}int main()
{int t, i, f, j;char ch;cin >> t; // 组数ch = getchar(); // 舍弃换行符for (i = 0; i < t; i++){f = 0; // 正确char* p = new char[9];cin >> p; // 读取一行输入,最多8个字符和一个结束字符int len = strlen(p); // 获取输入的长度if (len != 7) // 如果输入的长度不是7,标记为非法输入{f = 1;}else{for (j = 0; j < len; j++){if ((*(p + j) - '0') < 0 || (*(p + j) - '9') > 9){f = 1; // 输入不为数字break;}}}if (*p == '0' || *p == '1' || *p == '9') // 如果第一位的数字是019{f = 1; // 错误}if (f == 1) // 非法输入{cout << "Illegal phone number" << endl;}else{CTelNumber pp(p); // 设置7位电话号码CTelNumber p2(pp); // 调用拷贝构造函数p2.print();}delete[] p;}return 0;
}

id:52 D.软件备份(拷贝构造函数)

题目描述

软件作为一种对象也可以用类来描述,软件的属性包括软件名称、类型(分别用O、T和B表示原版、试用版还是备份)、有效截止日期(用CDate类子对象表示)和存储介质(分别用D、H和U表示光盘、磁盘和U盘)等。软件拷贝可通过拷贝构造函数来实现,此时在拷贝构造函数中软件类型改成“B”, 存储介质改为"H",其它不变。试完成该类的拷贝构造、构造和打印(包括从2015年4月7日算起有效期还有多少天,是否过期)成员函数的实现。

当输入软件有效截止日期是0年0月0日,表示无日期限制,为unlimited;当输入日期在2015年4月7日之前,则是过期,表示为expired;如果输入日期在2015年4月7日之后,则显示之后的剩余天数。具体输出信息看输出范例。

附CDate类的实现:

class CDate
{private:int year, month, day;public:CDate(int y, int m, int d);bool isLeapYear();int getYear();int getMonth();int getDay();int getDayofYear();
};CDate::CDate(int y, int m, int d)
{ year = y, month = m,day = d;
}bool CDate::isLeapYear()
{ return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; 
}int CDate::getYear()
{ return year;
}int CDate::getMonth() 
{ return month;
}int CDate::getDay() 
{ return day;
}int CDate::getDayofYear()
{int i, sum = day;int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};if (isLeapYear()){a[2]++;}// 求日期的天数for (i = 0; i < month; i++){sum += a[i];}return sum;
}

输入

测试数据的组数 t第一个软件名称第一个软件类型  第一个软件介质类型  第一个软件有效期年 月 日第二个软件名称第二个软件类型 第二个软件介质类型 第二个软件有效期年 月 日......注意:软件名称最大长度为30

输入

name: 第一个软件名称type: 第一个软件类型media: 第一个软件介质类型第一个软件2015-4-7后的有效天数name: 第一个软件名称type: backupmedia: hard disk第一个软件2015-4-7后的有效天数......

输入样例1

3
Photoshop_CS5
O D 0 0 0
Audition_3.0
B U 2015 2 3
Visual_Studio_2010
T H 2015 5 5

输出样例1

name:Photoshop_CS5
type:original
media:optical disk
this software has unlimited use

name:Photoshop_CS5
type:backup
media:hard disk
this software has unlimited use

name:Audition_3.0
type:backup
media:USB disk
this software has expired

name:Audition_3.0
type:backup
media:hard disk
this software has expired

name:Visual_Studio_2010
type:trial
media:hard disk
this software is going to be expired in 28 days

name:Visual_Studio_2010
type:backup
media:hard disk
this software is going to be expired in 28 days

输入样例2

2
Photoshop_CS5
O D 2015 4 8
Audition_3.0
B U 2023 4 7

输出样例2

name:Photoshop_CS5
type:original
media:optical disk
this software is going to be expired in 1 days

name:Photoshop_CS5
type:backup
media:hard disk
this software is going to be expired in 1 days

name:Audition_3.0
type:backup
media:USB disk
this software is going to be expired in 2922 days

name:Audition_3.0
type:backup
media:hard disk
this software is going to be expired in 2922 days

题解

  • CDate类:定义三个私有变量,年月日,定义六个公有函数,CDate(int y, int m, int d); // 构造函数初始化bool isLeapYear(); // 判断是否是闰年int getYear(); // 返回年份int getMonth();int getDay();int getDayofYear();,返回一个整数,这个整数是这个日期前的天数的总和
  • CDate(int y, int m, int d);,将参数的值传入年月日中
  • bool isLeapYear();,如果是闰年,返回1,否则,返回0
  • int getYear();int getMonth();int getDay();,分别返回调用这个函数的变量的年月日
  • int CDate::getDayofYear();,题目给出的函数,定义一个存放12个月份的天数的数组,然后把这个月份之前的月份的天数累加,再加上这个月份的天数,得到的结果即为这个日期前所有的月份总和,把值返回
  • Soft类:定义四个私有变量,软件名称,软件类型,有效日期和存储介质;和四个公有函数,Soft(const Soft &s1); // 软件拷贝Soft(char *m, char n, char p, CDate d); // 构造初始化void print(); // 打印 ~Soft(); // 析构函数释放内存
  • Soft::Soft(const Soft &s1) // 拷贝构造函数;,首先用: dd(s1.dd) // 初始化来进行对日期的初始化,因为日期不是一个指针,所以可以这样对其赋值,然后计算软件名称的字节数,动态分配这个字节数加1的内存给name,加1是为了在末尾处放上字符串结束符,然后使用strncpy函数对其赋值,由于软件名称和存储介质都是单个字符型,所以可以直接使用赋值号对其进行赋值,软件类型改为‘B‘,存储介质改为’H‘
  • Soft::Soft(char *m, char n, char p, CDate d) // 构造,构造函数和拷贝构造函数大同小异
  • void Soft::print();,输出函数,按照输出样例,分不同的情况进行不同的输出,注意后面有效天数的年份大于2015年时的计算
  • Soft::~Soft();,析构函数,释放软件名称内存
  • 主函数中,进行输入,初始化,拷贝构造,打印,释放内存即可

代码实现

#include <iostream>
#include <cstring>
using namespace std;class CDate
{
private:int year, month, day;public:CDate(int y, int m, int d); // 构造函数初始化bool isLeapYear();          // 判断是否是闰年int getYear();              // 返回年份int getMonth();int getDay();int getDayofYear();
};CDate::CDate(int y, int m, int d)
{year = y;month = m;day = d;
}bool CDate::isLeapYear()
{return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
}int CDate::getYear()
{return year;
}int CDate::getMonth()
{return month;
}int CDate::getDay()
{return day;
}int CDate::getDayofYear()
{int i, sum;int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};sum = day;if (isLeapYear()) // 如果是闰年{a[2]++; // 有29号}// 求日期的天数for (i = 0; i < month; i++){sum += a[i];}return sum;
}class Soft
{
private:char *name; // 软件名称char type;  // 软件类型CDate dd;char media; // 存储介质
public:Soft(const Soft &s1);                   // 软件拷贝Soft(char *m, char n, char p, CDate d); // 构造初始化void print();                           // 打印~Soft();                                // 析构函数释放内存
};Soft::Soft(const Soft &s1) // 拷贝构造函数: dd(s1.dd)            // 初始化
{int len = strlen(s1.name);name = new char[len + 1];strncpy(name, s1.name, len);type = 'B';media = 'H';name[len] = '\0';
}Soft::Soft(char *m, char n, char p, CDate d) // 构造: dd(d)
{int len = strlen(m);name = new char[len + 1];strncpy(name, m, len);type = n;media = p;name[len] = '\0';
}void Soft::print()
{int t, x, i, sum, n;t = 0; // 未过期cout << "name:" << name << endl;if (type == 'O'){cout << "type:original" << endl;}else if (type == 'B'){cout << "type:backup" << endl;}else if (type == 'T'){cout << "type:trial" << endl;}if (media == 'D'){cout << "media:optical disk" << endl;}else if (media == 'U'){cout << "media:USB disk" << endl;}else if (media == 'H'){cout << "media:hard disk" << endl;}if (dd.getYear() == 0 && dd.getMonth() == 0 && dd.getDay() == 0){t = 2; // 无日期}else if (dd.getYear() < 2015 || (dd.getYear() == 2015 && dd.getMonth() < 4) || (dd.getYear() == 2015 && dd.getMonth() == 4 && dd.getDay() < 7)){t = 1; // 过期}if (t == 2) // 无日期{cout << "this software has unlimited use" << endl;}else if (t == 1) // 过期{cout << "this software has expired" << endl;}else{sum = 0; // 总的天数if (dd.getYear() > 2015){x = dd.getYear() - 2015; // 和15年的差值for (i = 1; i < x; i++){n = 2015 + i;CDate d1(n, dd.getMonth(), dd.getDay());if (d1.isLeapYear()) // 如果是闰年{sum += 366;}else // 平年{sum += 365;}}sum += dd.getDayofYear();cout << "this software is going to be expired in " << sum + 268 << " days" << endl;}else{sum = dd.getDayofYear();cout << "this software is going to be expired in " << sum - 97 << " days" << endl;}}cout << endl;
}Soft::~Soft()
{delete[] name;
}int main()
{int t, i, yy, mm, dd;char *na, ty, me, ch;cin >> t; // 组数ch = getchar();na = new char[31];for (i = 0; i < t; i++){cin >> na >> ty >> me >> yy >> mm >> dd;CDate d(yy, mm, dd);   // 初始化日期Soft s(na, ty, me, d); // 初始化软件的属性s.print();Soft s1(s); // 拷贝构造s1.print();}delete[] na;return 0;
}

id:53 E.手机服务(构造+拷贝构造+堆)

题目描述

设计一个类来实现手机的功能。它包含私有属性:号码类型、号码、号码状态、停机日期;包含方法:构造、拷贝构造、打印、停机。

  1. 号码类型表示用户类别,只用单个字母,A表示机构,B表示企业、C表示个人
  2. 号码是11位整数,用一个字符串表示
  3. 号码状态用一个数字表示,1、2、3分别表示在用、未用、停用
  4. 停机日期是一个日期对象指针,在初始化时该成员指向空,该日期类包含私有属性年月日,以及构造函数和打印函数等

  1. 构造函数的作用就是接受外来参数,并设置各个属性值,并输出提示信息,看示例输出

  2. 拷贝构造的作用是复制已有对象的信息,并输出提示信息,看示例输出。
    想一下停机日期该如何复制,没有停机如何复制??已经停机又如何复制??

  3. 打印功能是把对象的所有属性都输出,输出格式看示例

  4. 停机功能是停用当前号码,参数是停机日期,无返回值,操作是把状态改成停用,并停机日期指针创建为动态对象,并根据参数来设置停机日期,最后输出提示信息,看示例输出


要求:在主函数中实现号码备份的功能,对已有的虚拟手机号的所有信息进行复制,并将号码类型改成D表示备份;将手机号码末尾加字母X

输入

第一行输入t表示有t个号码

第二行输入6个参数,包括号码类型、号码、状态、停机的年、月、日,用空格隔开

依次输入t行

输出

每个示例输出三行,依次输出原号码信息、备份号码信息和原号码停机后的信息

每个示例之间用短划线(四个)分割开,看示例输出

输入样例1

2
A 15712345678 1 2023 1 1
B 13287654321 2 2012 12 12

输出样例1

Construct a new phone 15712345678
类型=机构||号码=15712345678||State=在用
Construct a copy of phone 15712345678
类型=备份||号码=15712345678X||State=在用
Stop the phone 15712345678
类型=机构||号码=15712345678||State=停用||停机日期=2023.1.1
----
Construct a new phone 13287654321
类型=企业||号码=13287654321||State=未用
Construct a copy of phone 13287654321
类型=备份||号码=13287654321X||State=未用
Stop the phone 13287654321
类型=企业||号码=13287654321||State=停用||停机日期=2012.12.12
----

输入样例2

1
C 15674561389 3 2020 1 2

输出样例2

Construct a new phone 15674561389
类型=个人||号码=15674561389||State=停用
Construct a copy of phone 15674561389
类型=备份||号码=15674561389X||State=停用
Stop the phone 15674561389
类型=个人||号码=15674561389||State=停用||停机日期=2020.1.2
----

题解

  • Date类:有三个私有变量,分别是年月日;两个公有函数,一个是构造函数,作用是给变量初始化,赋予参数的值,还有一个是打印函数,作用是打印出停机日期
  • Phone类:定义三个私有变量,一个是char型的号码类型,一个是字符指针号码,一个是整数型的号码状态,还有一个是Date型的指针表示停机日期;五个公有的函数,一个是构造函数,用于初始化四个变量的值,一个是拷贝构造函数,一个是打印函数,一个是析构函数,还有一个是用于处理停机的函数
  • 下面来分别分析各个公有的函数,Phone(char t, char *n, int s, Date *d); // 构造,构造函数,用于将参数的值传入四个私有变量中,参数的类型与四个私有变量的类型应该要一致,在这个函数中,因为号码类型是字符型,所以我们可以直接使用赋值号“=”来对号码类型赋值;由于号码的类型是字符指针型,所以我们不能使用赋值号对其进行赋值,因为在析构函数中可能会重复释放相同的一片内存,造成程序崩溃,所以我们可以使用strncpy函数,其中,为这个变量开辟的空间大小要比需要复制给他的变量的字节数加一,这是因为多出来的一个字节用来存放字符串结束符\0,计算参数的变量我们可以使用strlen函数,使用这两个函数我们需要调用头文件cstring;号码状态是整数型,可以直接使用赋值号来进行复制;因为停机日期是Date类型的指针,如果我们也使用:day(d)来对day进行赋值的话,这个day也会和被赋值的day指向同一片内存空间,在析构函数中也会被重复释放,所以我们使用day = new Date(*d); // 创建新的Date对象这种方法来对day进行赋值,这行代码的含义是创建一个新的 Date 对象,并将指针 d 所指向的 Date 对象的内容(即 *d)作为参数传递给构造函数。在这行代码中,假设 d 是一个指向 Date 对象的指针,*d 则是解引用操作符,表示获取指针 d 所指向的 Date 对象的值。所以,这行代码的作用是利用指针 d 所指向的 Date 对象的值来初始化一个新的 Date 对象,这样就创建了一个新的 Date 对象,其内容与原始对象相同。
  • Phone(const Phone &p1); // 拷贝构造,拷贝构造函数,看输出样例可知,我们需要额外的创建一个变量,将第一次用Phone类型创建的变量赋值到这个新的创建的变量中,然后要改变这个新的创建的变量的号码类型,变为“备份”;然后同样的方法赋值号码,但有所区别的是,这次我们为num开辟的空间要比被拷贝的变量的字节多两个,一个用来存储末尾的X,一个用来存储字符串结束符;同样的方法赋值号码状态和停机日期
  • 在打印函数中,看输出样例,每个不同的类型的处理的第一行输出都不相同,在打印函数中难以做到条件判断,所以每个类型的第一行输出我们把它放在主函数中输出,然后我们可以在打印函数中处理中间的输出;首先判断号码类型,不同的类型输出不同的中文,然后输出号码状态,由于最后一个打印的停机类型的第一行输出又有所特殊,在主函数中不能直接调用停机日期,所以我们考虑在停机函数中输出第一行,然后最后要输出的停机日期中文也在主函数中输出,日期就调用Date类型的输出函数即可
  • 在析构函数中我们需要释放两个变量的内存,一个是num,一个是day
  • 在停机函数中,我们需要将号码状态改为停机,然后输出最后一个停机的第一行输出
  • 在主函数中,我们先输入有多少个号码,然后处理最后一个回车符,因为后一个是一个字符型输入;号码也是定义为字符型指针,动态创建内存,记得最后释放;最后就是输入和一些初始化和输出

遇到的问题

  • 不知道停机函数如何实现,拷贝函数在数组末尾加X
  • 使用:day(d)初始化,导致后面的析构函数重复释放内存
  • 忘记在字符串末尾添加结束符
  • 输出函数过于混乱

代码实现

#include <iostream>
#include <cstring>
using namespace std;class Date
{
private:int year;int month;int day;public:Date(int y, int m, int d); // 构造函数void print();              // 打印函数
};Date::Date(int y, int m, int d) // 构造初始化
{year = y;month = m;day = d;
}void Date::print()
{cout << year << "." << month << "." << day << endl;;
}class Phone
{
private:char type; // 号码类型char *num; // 号码int state; // 号码状态Date *day; // 停机日期
public:Phone(char t, char *n, int s, Date *d); // 构造Phone(const Phone &p1);                 // 拷贝构造void print();                           // 打印~Phone();                               // 析构释放内存void stop(Date* d);                     // 停机
};Phone::Phone(char t, char *n, int s, Date *d) // 初始化
{type = t;int len = strlen(n);num = new char[len + 1]; // 额外的空间用于添加'X'strncpy(num, n, len);num[len] = '\0';state = s;day = new Date(*d); // 创建新的Date对象
}Phone::Phone(const Phone &p1)
{type = 'D'; // 表示备份int len = strlen(p1.num);num = new char[len + 2];strncpy(num, p1.num, len);num[len] = 'X';num[len + 1] = '\0';state = p1.state;day = new Date(*(p1.day));
}void Phone::print()
{if (type == 'A') // 输出类型{cout << "类型=机构||号码";}else if (type == 'B'){cout << "类型=企业||号码";}else if (type == 'C'){cout << "类型=个人||号码";}else{cout << "类型=备份||号码";}cout << "=" << num << "||State=";if (state == 1) // 输出号码状态{cout << "在用";}else if (state == 2){cout << "未用";}else{cout << "停用";}
}Phone::~Phone()
{delete[] num; // 释放动态分配的内存delete day;
}void Phone::stop(Date* d)
{state = 3; // 号码状态改为停机cout << "Stop the phone " << num << endl;
}int main()
{int t, i, st, yy, mm, dd;char ty, ch, *num;cin >> t; // t个号码ch = getchar();num = new char[12];for (i = 0; i < t; i++){cin >> ty >> num >> st >> yy >> mm >> dd;Date d1(yy, mm, dd);       // 日期初始化Phone p1(ty, num, st, &d1); // 手机初始化cout << "Construct a new phone " << num << endl; // 输出号码p1.print();                // 打印Phone p2(p1);              // 拷贝cout << endl << "Construct a copy of phone " << num << endl; // 备份p2.print();cout << endl;p1.stop(&d1); // 停机p1.print();cout << "||停机日期=";d1.print();cout << "----" << endl;}delete[] num;return 0;
}

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

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

相关文章

VS2019中配置C++ OpenCV 4.5.4完整指南

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的在读研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三…

STM32标准库ADC和DMA知识点总结

目录 前言 一、ADC模数转换器 &#xff08;1&#xff09;AD单通道 &#xff08;2&#xff09;AD多通道 二、DMA原理和应用 &#xff08;1&#xff09;DMA数据转运&#xff08;内存到内存&#xff09; &#xff08;2&#xff09;DMAAD多同道&#xff08;外设到内存&#x…

24深圳杯数学建模挑战赛A题6页初步思路+参考论文+保姆级答疑!!!

问题1:单个残骸的精确位置定位 建立数学模型&#xff0c;分析如果要精准确定空中单个残骸发生音爆时的位置坐标&#xff08;经度、纬度、高程&#xff09;和时间&#xff0c;至少需要布置几台监测设备&#xff1f;假设某火箭一级残骸分离后&#xff0c;在落点附近布置了7台监测…

【热门话题】AI作画算法原理解析

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 AI作画算法原理解析AI作画算法概述基础原理&#xff1a;机器学习与深度学习卷积…

Bentley二次开发教程24-交互式类工具

交互式工具概念简述 本次内容主要涉及到交互式工具的使用&#xff0c;在MicroStation中&#xff0c;超过一半的功能都是以交互式工具的形式而存在的&#xff0c;因此交互式工具在MicroStation二次开发中便显得非常重要。当我们的鼠标或键盘在视图中产生交互操作时&#xff0c;…

黑马微服务课程2

课程地址&#xff1a;2024最新SpringCloud微服务开发与实战&#xff0c;java黑马商城项目微服务实战开发&#xff08;涵盖MybatisPlus、Docker、MQ、ES、Redis高级等&#xff09;_哔哩哔哩_bilibili 课程名称&#xff1a;2024最新SpringCloud微服务开发与实战&#xff0c;java…

《A More Fine-Grained Aspect-Sentiment-Opinion Triplet Extraction Task》阅读笔记

一、论文简介 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情感分析一直是一个热门的研究主题&#xff0c;它帮助机器理解文本中的情感倾向。随着技术的进步&#xff0c;研究者们不断推动情感分析向更细粒度的方向发展&#xff0c;即从简单的正负情感判断&#…

【VueUse】重新定义状态管理在 Vue 中的体验

在 Vue 生态系统中&#xff0c;状态管理一直是开发者们关注的焦点之一。而随着 VueUse 的出现&#xff0c;我们迎来了一种全新的方式来处理状态管理&#xff0c;它让我们能够以更简单、更灵活的方式来管理应用程序的状态。 在本文中我们将深入探讨 VueUse 中与状态管理相关的内…

StrongSORT——基于DeepSORT,提高多目标跟踪的准确性和鲁棒性

1、概述 1.1 DeepSORT DeepSORT算法是在SORT基础上发展起来的一种多目标跟踪算法。SORT算法结合了目标检测器和跟踪器&#xff0c;其中跟踪器的核心是卡尔曼滤波和匈牙利算法。 卡尔曼滤波用于预测目标在下一帧的位置和状态而匈牙利算法则用于将预测状态与实际检测结果进行最…

SpringCloud基础 Consul的引入

前言 首先是为什么引入consul这个组件 我们知道微服务分为很多个模块,这里模块中相互调用,我使用硬编码的模式是不好的 比如微服务模块需要更新的时候,我们使用硬编码的方式可能需要修改很多个地方 但是使用consul之后,就引入了注册中心,我们只需要将对应的服务注册为节点 这样…

android脱壳第二发:grpc-dumpdex加修复

上一篇我写的dex脱壳&#xff0c;写到银行类型的app的dex修复问题&#xff0c;因为dex中被抽取出来的函数的code_item_off 的偏移所在的内存&#xff0c;不在dex文件范围内&#xff0c;所以需要进行一定的修复&#xff0c;然后就停止了。本来不打算接着搞得&#xff0c;但是写了…

【论文阅读】EgoPCA: A New Framework for Egocentric Hand-Object Interaction

论文主要贡献 提出一种新的框架&#xff1a;Ego-HOI recognition by Probing, Curation and Adaption (EgoPCA)。构建了全面的预训练集&#xff0c;平衡的测试集&#xff0c;以及一个包含了微调策略的baseline。 在Ego-HOI达到了SOTA&#xff0c;并且建立了有效的机制方法。 …

【后端】git与python的结合使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、git介绍二、git常见使用三、git与python的结合使用四、总结 前言 随着开发语言及人工智能工具的普及&#xff0c;使得越来越多的人会主动学习使用一些开发…

【OceanBase系列】—— 常用运维操作(备忘)

作者简介&#xff1a; 花名&#xff1a;绪宁&#xff0c;OceanBase 数据库解决方案架构师 创建租户 方法一&#xff1a;OCP 创建 确认可分配资源 具体可以分配多少内存&#xff0c;可以通过【资源管理】查看各节点的剩余资源 2. 新建租户 3. 填写租户信息 zone 优先级主要是 p…

STM32玩转物联网实战篇:5.ESP8266 WIFI模块MQTT通信示例详解

1、准备开发板 开发板功能区分布图 开发板俯视图 2、实验讲解 在之前的章节中&#xff0c;已经讲解过了MQTT的通讯原理和组包过程&#xff0c;现在开始手把手的教大家用代码来实现连接MQTT平台以及数据的交互&#xff0c;实际上这篇文章已经拖更接近两年了&#xff0c;非常…

《QT实用小工具·三十九》仿 Windows10 画图3D 的颜色选择器, 但更加强大

1、概述 源码放在文章末尾 该项目实现了仿 Windows10 画图3D 的颜色选择器&#xff0c;功能更加丰富更加强大。 项目部分代码如下所示&#xff1a; import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import QtGraphicalEffects 1.15Item {id…

【leetcode面试经典150题】72. 从前序与中序遍历序列构造二叉树(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

opencv绘制线段------c++

绘制线段 bool opencvTool::drawLines(std::string image_p, std::vector<cv::Point> points) {cv::Mat ima cv::imread(image_p.c_str()); // 读取图像&#xff0c;替换为你的图片路径 cv::Scalar red cv::Scalar(0, 0, 255); // Red color int thickness 2;// 遍…

面试遇到算法题:实现LRU缓存

请你设计并实现一个满足 LRU (最近最少使用) 缓存约束的数据结构。 这是一道大厂面试高频出现的算法题&#xff0c;难度为⭐️⭐️⭐️&#xff0c;属于中等&#xff0c;老铁们来一起看看这个题该怎么解&#xff1f; 1. 原题再现 没有废话&#xff0c;翠花&#xff0c;上酸菜&…

JS 添加数组元素( 4种方法 )

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 一、四种…