C++实验课拷贝构造函数练习

文章目录

  • 【id:51】【20分】C. 电话号码升位(拷贝构造函数)
  • 【id:52】【20分】D. 软件备份(拷贝构造函数)
  • 【id:53】【20分】E. 手机服务(构造+拷贝构造+堆)
  • 总结


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

题目描述

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

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

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

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

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

输入

测试数据的组数 t

第一个7位号码

第二个7位号码

输出

第一个号码升位后的号码

第二个号码升位后的号码

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


输入样例

3
6545889
3335656
565655

输出样例

26545889
83335656
Illegal phone number

解题思路:注意!!!这里题目所说的号码非法输入包括了号码长度不为7、号码非数字和能升级成功的号码(不以2、3、4、5、6、7、8开头的号码)。这题的思路为:先创建字符数组,判断输入是否为合法电话号码。如果是的话就用该字符数组创建对象,用创建对象拷贝构造一个新的对象以实现号码升级。

#include
#include
using namespace std;

class CTelNumber
{
private:
	char* p;
public:
	CTelNumber(char* point);  //构造函数
	~CTelNumber();   //析构函数
	CTelNumber(const CTelNumber&a);//拷贝构造函数
};
CTelNumber::CTelNumber(char* point)
{
	p = new char[8];  
	for (int i = 0; i < 8; i++)
	{
		p[i] = *point;
		point++;
	}

}
CTelNumber::~CTelNumber()
{
	delete[]p;
}
CTelNumber::CTelNumber(const CTelNumber& a)
{
	p = new char[9]; //加多一位
	if (a.p[0] == '2' || a.p[0] == '3' || a.p[0] == '4')  //判断情况
	{
		p[0]='8';  //首位为8,其余的拷贝
		int k = 0;
		for (int i = 1; i < 9; i++,k++)
		{
			p[i] = a.p[k];   //拷贝操作
		}
	}
	else if (a.p[0] == '5' || a.p[0] == '6' || a.p[0] == '7' || a.p[0] == '8')  //同上
	{
		p[0] = '2';
		int k = 0;
		for (int i = 1; i < 9; i++, k++)
		{
			p[i] = a.p[k];
		}
	}
	cout << p << endl;
}

int isDigtal(char* p)
{
	int num = 0;
	if (p[0] < '2' || p[0]> '8')  //判断不能升级的号码
	{
		return 0;
	}
	for (int i = 0;p[i] != '\0' && p[i] >= '0' && p[i] <= '9'; i++)//判断字符是否为数字
	{
		num++;
	}
	if (num == 7)//判断数字的个数
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		char p[8];  //7个数字+'\0'共8个字符
		cin >> p;//注意像这样直接输入编译器会自动帮我们在后面补上'\0'
		if (isDigtal(p))//判断号码是否合法
		{
			CTelNumber old(p);//构造一个对象
			CTelNumber newtel(old);//拷贝构造

		}
		else
		{
			cout << "Illegal phone number" << endl;
		}
	}

	//system("pause");
	return 0;
}

【id:52】【20分】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日之后,则显示之后的剩余天数。具体输出信息看输出范例。

输入

测试数据的组数 t

第一个软件名称

第一个软件类型 第一个软件介质类型 第一个软件有效期年 月 日

第二个软件名称

第二个软件类型 第二个软件介质类型 第二个软件有效期年 月 日

注意:软件名称最大长度为30;

输出

name: 第一个软件名称

类型: 第一个软件类型

media: 第一个软件介质类型

第一个软件2015-4-7后的有效天数

name: 第一个软件名称

类型: 备份

介质:硬盘

第一个软件2015-4-7后的有效天数


输入样例

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

输出样例

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

#include
using namespace std;

class CDate

{

private:

    int year, month, day;

public:

    CDate(int y, int m, int d);

    CDate();

    bool isLeapYear();

    int getYear();

    int getMonth();

    int getDay();

    int getDayofYear();

};

CDate::CDate()
{
    
}

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;

}

class Software
{
private:
	char* name;
	char m_type;
    CDate limit_day;
    char m_media;
public:
    Software(char*p,char type,char media,CDate day);//构造函数
    ~Software();  //析构函数
    Software(const Software& s);//拷贝构造函数
    void print();
    int calculate();//计算
};

Software::Software(char* p, char type, char media, CDate day)
{
    int n = 0;
    for (int i=0;p[i] != '\0';i++)
    {
        n++;  //计算字符数
    }
    name = new char[n+1];  //记得最后还有'\0'
    for (int i = 0; i < n; i++)
    {
        name[i] = p[i];  //逐一拷贝
    }
    name[n] = '\0';
    m_type = type;
    m_media = media;
    limit_day = day;
}
Software::~Software()
{
    delete[]name;
}
Software::Software(const Software& s) :limit_day(s.limit_day)
{
    int n = 0;
    for (int i = 0; s.name[i] != '\0'; i++)
    {
        n++;
    }
    name = new char[n + 1];
    for (int i = 0; i < n; i++)
    {
        name[i] = s.name[i];
    }
    name[n] = '\0';
    m_type = 'B';
    m_media = 'H';
}
int Software::calculate()//判断是否过期
{
    if (limit_day.getYear() == 0 && limit_day.getMonth() == 0 && limit_day.getDay() == 0)
    {
        return 1;
    }
    else if (limit_day.getYear() <= 2015 && limit_day.getMonth() <= 4 && limit_day.getDay() < 7)
    {
        return 2;
    }
    else  //计算剩余几天过期
    {
        int result=0;
        CDate date(2015, 4, 7);
        result = limit_day.getDayofYear() - date.getDayofYear();
        return result;
    }
}
void Software::print()
{
    cout << "name:" << name << endl;
    cout << "type:";
    if (m_type == 'O')
    {
        cout << "original" << endl;
    }
    else if (m_type == 'B')
    {
        cout << "backup" << endl;
    }
    else
    {
        cout << "trial" << endl;
    }
    cout << "media:";
    if (m_media == 'D')
    {
        cout << "optical disk" << endl;
    }
    else if (m_media == 'H')
    {
        cout << "hard disk" << endl;
    }
    else
    {
        cout << "USB disk" << endl;
    }
    int flag = this->calculate();
    if (flag == 1)
    {
        cout << "this software has unlimited use" << endl;
    }
    else if (flag == 2)
    {
        cout << "this software has expired" << endl;
    }
    else
    {
        cout << "this software is going to be expired in " << flag << " days" << endl;
    }
    
}

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        char p[30];
        char type;
        char media;
        int year, month, day;
        cin >> p >> type >> media>>year>>month>>day;
        CDate date(year, month, day);  //先构造日期
        Software my_software(p, type, media, date);//再构造软件类
        my_software.print();//打印信息
        Software copy_software(my_software);//拷贝构造
        copy_software.print();

    }

	system("pause");
	return 0;
}

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

题目描述

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

5、构造函数的作用就是接受外来参数,并设置各个属性值,并输出提示信息,看示例输出
6、拷贝构造的作用是复制已有对象的信息,并输出提示信息,看示例输出。
想一下停机日期该如何复制,没有停机如何复制??已经停机又如何复制??

7、打印功能是把对象的所有属性都输出,输出格式看示例
8、停机功能是停用当前号码,参数是停机日期,无返回值,操作是把状态改成停用,并停机日期指针创建为动态对象,并根据参数来设置停机日期,最后输出提示信息,看示例输出


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

输入

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

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

依次输入t行

输出

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

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


输入样例1

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

输出样例

Construct a new phone 15712345678
类型=机构||号码=15712345678||State=在用
Construct a copy of phone 15712345678
类型=备份||号码=15712345678X||State=在用
Stop the phone 15712345678
类型=机构||号码=15712345678||State=停用 ||停机日期=2015.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
----

#include
using namespace std;

class CDate
{
private:
	int year;
	int month;
	int day;
public:
	CDate();
	CDate(int y, int m, int d);
	int getYear();
	int getMonth();
	int getDay();
	void print();
};
CDate::CDate()
{

}
CDate::CDate(int y, int m, int d)
{
	year = y;
	month = m;
	day = d;
}
int CDate::getMonth()
{
	return month;
}
int CDate::getDay()
{
	return day;
}
int CDate::getYear()
{
	return year;
}
void CDate::print()//用于打印停机信息
{
	cout << "停机日期=" << year << '.' << month << '.' << day<<endl;
}

class Phone
{
private:
	char type;
	char *num;
	char state;
	CDate* date=NULL;
public:
	Phone(char t,char*n,char s);//构造函数
	Phone(const Phone& p);//拷贝构造函数
	~Phone();//析构函数
	void stop(CDate &a);
	void print();


};
Phone::Phone(char t, char* n, char s)
{
	type = t;
	num = new char[15];
	for (int i = 0; i < 12; i++)
	{
		num[i] = n[i];
	}
	num[12] = '\0';
	state = s;
	cout << "Construct a new phone " <<num<< endl;
}
Phone::Phone(const Phone& p)
{
	cout << "Construct a copy of phone " << p.num << endl;
	type = 'D';
	num = new char[15];
	for (int i = 0; i < 11; i++)
	{
		num[i] = p.num[i];
	}
	num[11] = 'X';
	num[12] = '\0';
	state = p.state;
	if (p.date != NULL)
	{
		date = new CDate(*p.date);
	}
}
Phone::~Phone()
{
	delete[]num;
	if(date!=NULL)
	delete date;
}
void Phone::stop(CDate &a)//停机函数
{
	state = '3';
	date = new CDate(a.getYear(), a.getMonth(), a.getDay());
	cout << "Stop the phone " << num << endl;
}
void Phone::print()
{
	cout << "类型=";
	if (type == 'A')
	{
		cout << "机构||号码=" << num;
	}
	else if (type == 'B')
	{
		cout << "企业||号码=" << num;
	}
	else if(type=='C')
	{
		cout << "个人||号码=" << num;
	}
	else
	{
		cout << "备份||号码=" << num;
	}
	cout << "||State=";
	if (state == '1')
	{
		cout << "在用" << endl;
	}
	else if (state == '2')
	{
		cout << "未用" << endl;
	}
	else
	{
		cout << "停用 ||";
		this->date->print();
	}
}

int main()
{
	int t, y, m, d;
	char s;
	char type;
	char num[15];
	cin >> t;
	while (t--)
	{
		cin >> type >> num >> s >> y >> m >> d;
		CDate date(y, m, d);
		Phone p1(type, num, s);
		p1.print();
		Phone p2(p1);
		p2.print();
		p1.stop(date);
		p1.print();
		cout << "- - - -" << endl;
	}

	//system("pause");
	return 0;
}

总结

现阶段的C++其实逻辑思维不难,只需要耐心、细心地写好类方法和实现就行。继续加油!

你可能感兴趣的:(c++)