[C++]8.3-8.4 析构函数,复制构造函数(深拷贝)(作业)

Posted Tranquility_5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C++]8.3-8.4 析构函数,复制构造函数(深拷贝)(作业)相关的知识,希望对你有一定的参考价值。

[C++]8.3-8.4 析构函数,复制构造函数(深拷贝)(作业)

看到了就点个赞赞嘛~ ヾ(≧▽≦*)o~

第六周作业

*初学C++,想要把每周老师布置的实验题和自己写的程序记录下来,方便期末整理复习,请多多指教!
老师要求用的版本比较老,是Microsoft Visual C++ 2010 Express。
*)

一、 集合类的声明和对象的定义

声明一个集合类,有成员数据:int a[10];

成员函数
构造函数(要求完成对数组a中所有元素的初始化);
输出的成员函数,要求每行输出5个数;
判断一个数是否在数组中的函数,如果在数组中,返回数组中下标的值。

main()完成对象的定义和相关成员函数的测试。

#include<iostream>
using namespace std;

class A

	int a[10];
public:
	A(int b[10])
	
		int i;
		for(i=0;i<10;i++)
			a[i]=b[i];
	
	void Cout()
	
		int i;
		for(i=0;i<10;i++)
		
			if(i%5==0)cout<<'\\n';
			cout<<a[i]<<'\\t';
		
		cout<<'\\n';
	
	void Check(int p)
	
		int i,t=0;
		for(i=0;i<10;i++)
			if(p==a[i])
				cout<<"您所需要找的数在数组中,下标为:"<<i<<endl,t++;
		if(!t)cout<<"没有找到!"<<endl;
	

;

void main()

	int b[10],j,p;
	cout<<"请给数组中的十个数赋值(整型数):"<<endl;
	for(j=0;j<10;j++)cin>>b[j];
	A A1(b);
	A1.Cout();
	cout<<"请输入需要检查的整型数:"<<'\\n'<<endl;
	cin>>p;
	A1.Check(p);

	getchar();
	getchar();


二、职工类的声明和对象的定义

1.题目要求

声明一个职工类,有成员数据:工号、姓名、性别、基本工资、奖金、总工资;要求有如下成员函数:构造函数修改基本工资奖金的函数输出所有成员的函数
main()完成对象的定义和有关成员函数的测试。

2.分析

构造函数中,总工资可以通过计算得到,所以不需要通过形式参数对总工资进行初始化。

请完成程序代码的编写、调试,并得到正确结果。

声明一个职工类,有成员数据:工号、姓名、性别、基本工资、奖金、总工资;要求有如下成员函数:
构造函数、修改基本工资和奖金的函数、输出所有成员的函数。
main()完成对象的定义和有关成员函数的测试。*/
#include<iostream>
#include<string>
#include<cstring>
#include <stdlib.h>
using namespace std;

class workers

	double Num;
	char Name[10],Sex[5];
	double Pay,Bonus,SumPay;
public:
	workers(double num,char name[10],char sex[5],double pay,double bonus)
	
		Num=num,Pay=pay,Bonus=bonus;
		strcpy(Name,name),strcpy(Sex,sex);
		cout<<"构造函数被调用"<<endl;
	
	void renew(double pay,double bonus)
	
		Pay=pay;
		Bonus=bonus;
	
	void Display()
	
		SumPay=Pay+Bonus;
		cout<<"工号:"<<Num<<'\\t'<<"姓名:"<<Name<<'\\t'<<"性别:"<<Sex<<endl;
		cout<<"基本工资:"<<Pay<<'\\t'<<"奖金:"<<Bonus<<'\\t'<<"总工资:"<<SumPay<<'\\n'<<endl;

	

;

void main()

	int num;
	char name[10],sex[5];
	double pay,bonus,b,p;
	cout<<"请输入工人的工号(纯数字)、姓名"<<endl;
	cin>>num;
	
	cin.getline(name,10);
	cout<<"请输入工人的性别:"<<endl;
	cin.getline(sex,4);
	cout<<"请输入工人基本工资,奖金:"<<endl;
	cin>>pay>>bonus;

	workers w1(num,name,sex,pay,bonus);
	w1.Display();
	cout<<"请输入更改后的基本工资和奖金:"<<endl;
	cin>>p>>b;

	w1.renew(p,b);
	w1.Display();

	getchar();
	getchar();

三、通讯录类的声明和对象的定义

声明一个通讯录类,含姓名、地址、电话号码成员数据,其中 姓名电话号码使用字符数组, 地址 使用字符类型的指针成员

要求有如下成员函数:
构造函数拷贝构造函数析构函数输出所有成员的函数

main()完成对象的定义和有关成员函数的测试。

/*通讯录类的声明和对象的定义
声明一个通讯录类,含姓名、地址、电话号码成员数据,其中姓名和电话号码使用字符数组,地址
使用字符类型的指针成员。要求有如下成员函数:构造函数、拷贝构造函数、析构函数、输出所有成员的函数。
main()完成对象的定义和有关成员函数的测试。
*/
#include<iostream>
#include<string>
using namespace std;
class list

	char Name[50],Num[30];
	char *Addr;
public:
	list(char *name,char *num,char*addr)
	
		strcpy(Name,name);
		strcpy(Num,num);
		Addr=new char[strlen(name)+1];
		strcpy(Addr,addr);
		cout<<"调用了构造函数"<<endl;
	
	list(list &p)
	
		strcpy(Name,p.Name);
		strcpy(Num,p.Num);
		if(p.Addr)
			Addr=new char[strlen(p.Addr)+1];
			strcpy(Addr,p.Addr);
		else Addr=0;
		cout<<"调用了复制构造函数"<<endl;

	
	~list()
	
		if(Addr) delete[]Addr;
		cout<<"调用了析构函数"<<endl;
	
	void Display()
	
		cout<<"姓名:"<<Name<<'\\t'<<"电话号码:"<<Num<<'\\t'<<"地址"<<Addr<<endl;
	

;
void main()

	char name[50],num[30],a[100];
	char *addr=a;
	cout<<"请输入联系人的姓名:"<<endl;
	cin.getline(name,50);
	cout<<"请输入联系人的电话号码:"<<endl;
	cin.getline(num,30);
	cout<<"请输入联系人的家庭住址:"<<endl;
	cin.getline(a,100);
	list L1(name,num,addr),L2(L1);
	L1.Display();
	L2.Display();
	L2.~list();
	L1.~list();

	getchar();
	getchar();
	


四、线性表类的声明和对象的定义:

声明一个线性表类,有成员数据: float * List;(指向线性表的指针)、int Max;(线性表的长度)、int Num;(线性表中实际元素个数)。
要求有如下成员函数:构造函数、拷贝构造函数、析构函数、在线性表尾增加一个元素、输出所有成员的函数。
main()完成对象的定义和有关成员函数的测试

/*线性表类的声明和对象的定义:
声明-一个线性表类,有成员数据: float * List;(指向线性表的指针)、int Max;(线性表的长度)、int Num;(线性表中实际元素个数)。
要求有如下成员函数:构造函数、拷贝构造函数、析构函数、在线性表尾增加一个元素、输出所有成员的函数。
main()完成对象的定义和有关成员函数的测试。*/
#include<iostream>
#include<string>
using namespace std;
class LineList

	float*List;
	int Max,Num;
public:
	LineList(int n=10)
	
		List=new float[n];
		Max=n;
		Num=0;
		cout<<"调用了构造函数"<<'\\n'<<endl;
	
	LineList(LineList &p)
	
		Max=p.Max;
		Num=p.Num;
		List=new float[p.Max];
		int i;
		for(i=0;i<Num;i++)
			List[i]=p.List[i];
		cout<<"调用了复制构造函数"<<'\\n'<<endl;
	
	~LineList()
	
		if(List) delete[]List;
		cout<<"调用了析构函数"<<'\\n'<<endl;
	
	void Add(float x)
	
		if(Num<Max)List[Num++]=x;
		else 
			float *list;int i;
			Max++,Num++;
			list=new float[Max+4];
			for(i=0;i<Num;i++)list[i]=List[i];
			delete List;
			list[i]=x;
			List=list;
		
	
	void Display()
	
		cout<<"线性表的长度:"<<'\\t'<<Max<<'\\t'<<"线性表中实际元素个数:"<<'\\t'<<Num<<endl;
		int i;
		for(i=0;i<Num;i++)
			cout<<List[i]<<'\\t';
		cout<<'\\n';
	
;
void main()

	int n,i,m,x;

	float a[88];
	
	cout<<"请输入线性表的长度n:"<<endl;
	cin>>n;
	cout<<"请输入线性表的线性表中实际元素个数m:"<<endl;
	cin>>m;

	cout<<"请依次输入线性表中的元素:"<<endl;
	
	for(i=0;i<m;i++)
		cin>>a[i];

	LineList L1(n);
	for(i=0;i<m;i++)
	
		L1.Add(a[i]);
	
	L1.Display();
	cout<<"请输入您想添加的一个实型数:"<<endl;
	cin>>x;
	L1.Add(x);
	cout<<"添加数字后的线性表为:"<<endl;
	L1.Display();
	LineList L2(L1);
	L2.Display();
	L2.~LineList();
	L1.~LineList();

	getchar();
	getchar();


c++ 复制构造函数和析构函数

【中文标题】c++ 复制构造函数和析构函数【英文标题】:c++ Copy constructors and destructors 【发布时间】:2018-07-05 07:56:16 【问题描述】:

我正在学习 C++ 中的构造函数和析构函数;帮助我抓住我的错误,即使它们很愚蠢......

这里是我编写的使用 C++ 中的类执行加法的代码;这将创建 datatype num 的两个求和,并使用构造函数 sum() 来执行两个数字的求和;然而,当一切顺利时,我偶然发现为 num 创建了一个复制构造函数,(虽然不是必需的,但仍然可以练习)......如果没有类 sum 的动态对象,就不可能无论如何运行代码(不删除复制构造函数)...帮助我改进我的代码和我在下面代码中的错误; 我也想知道如何在这个程序中使用复制构造函数;问题是在析构函数中,删除操作在同一块内存上执行了多次(我想)

这是我的代码

#include<iostream>
#include<new>
using namespace std;
class num

public:
    int *a;
    num(int x)
    
        try
        
            a=new int;
        
        catch(bad_alloc xa)
        
            cout<<"1";
            exit(1);
        
        *a=x;
    
    num()  
    num(const num &ob)
    
        try
        
            a=new int;
        
        catch(bad_alloc xa)
        
            cout<<"1''";
            exit(2);
        
        *a=*(ob.a);
    
    ~num()
     
        cout<<"Destruct!!!";
        delete a;
    
;


class sum:public num

 public:
     int add;
     sum(num n1,num n2)
     
         add=*(n1.a)+*(n2.a);
     
     int getsum()
     
         return add;
     
;

int main()

    num x=58;
    num y=82;
    sum *s=new sum(x,y);
    cout<<s->getsum();
    delete s;
    return 0;

【问题讨论】:

对于代码审查,您可以考虑前往CodeReview Stackexchange num() 这是非常错误的。你不能让你的指针数据成员未初始化。 为什么sum需要继承numsum(num n1,num n2) 更喜欢由const num&amp; 代替。 sum(const num&amp; n1, const num&amp; n2) 我认为num 不需要持有int *,而不仅仅是int。或者让它存在。只需在ints 上操作 【参考方案1】:

我可能会遗漏一些东西 - 没有使用 new/delete 太久,但尝试更正我注意到的所有内容。

附:始终使用智能指针。

#include <iostream>
#include <exception>
#include <new>

using namespace std;

int* allocate(const char* err_msg, int exit_code)

    int* a = nullptr;
    try
    
        a = new int;
    
    catch (bad_alloc&)
    
        cout << err_msg << endl;
        exit(exit_code);
    
    return a;


class num

    int* a = nullptr; // always should be initialized here

public:
    num() noexcept : a(nullptr) // or here
    

    /*explicit*/ num(int x) : a(allocate("1", 1))
    
        *a = x;
    

    num(const num& ob) : a(allocate("1''", 2))
    
        *a = *(ob.a);
    

    // rule of zero/three/five
    // default copy assignment will copy pointer and one int will be leaked and one will be deleted twice
    num& operator =(const num& ob)
    
        if (&ob == this)
        
            return *this;
        

        *a = *(ob.a);
        return *this;
    

    ~num()
     
        cout << "Destruct!!!";
        delete a;
        a = nullptr; // usefull for debug
    

    int value() const
    
        if (a == nullptr)
        
            throw runtime_error("a == nullptr");
        
        return *a;
    
;

class sum

    int add = 0;

public:
    sum(const num& n1, const num& n2)
    
        add = n1.value() + n2.value();
    

    int getsum() const
    
        return add;
    
;

int main()

    const num x = 58;
    const num y = 82;
    const sum* s = new sum(x, y);
    cout << s->getsum() << endl;
    delete s;
    return 0;

【讨论】:

感谢您的帮助; 还有一个;因为我是构造函数和异常的新手,所以你能解释一下 num() noexcept: a(nullptr) 和 0 3 和 5 的规则吗? 编译过程中出现几十个错误;我无法调试这些错误 @ArijitDey 您使用哪个编译器?下面是对 0/3/5 规则的解释:en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming) @ArijitDey num() noexcept: a(nullptr) 是用 0 初始化 a 的默认构造函数。

以上是关于[C++]8.3-8.4 析构函数,复制构造函数(深拷贝)(作业)的主要内容,如果未能解决你的问题,请参考以下文章

C++——构造函数析构函数以及复制构造函数

C++ 中类的默认成员函数的问题(构造函数、析构函数、运算符 =、复制构造函数)(默认 ctor、dtor、复制 ctor)

C++在单继承多继承虚继承时,构造函数复制构造函数赋值操作符析构函数的执行顺序和执行内容

C++类的成员函数:构造析构拷贝构造运算符重载

C++类的成员函数:构造析构拷贝构造运算符重载

C++类的成员函数:构造析构拷贝构造运算符重载