类和对象阶段考试总结

本文详细解析了C++中String类与Test类的构造、拷贝构造、赋值运算符重载及析构过程,并通过具体示例展示了不同情况下对象的创建与销毁过程。此外还介绍了Link类的实现,包括链表的基本操作如插入、删除等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目一:实现String类中的方法

class String
{
public:
	String(char *pstr)
	{
		_pstr = new char[strlen(pstr)+1];
		strcpy(_pstr,pstr);
		cout<<this<<endl;
		cout<<"String(char *)"<<endl;
		
	}
	~String()
	{
		delete[]_pstr;
		_pstr = NULL;
		cout<<this<<endl;
		cout<<"~String()"<<endl;
		
	}
	String(const String &src)//自定义拷贝构造函数
	{
		_pstr = new char[strlen(src._pstr)+1];
		strcpy(_pstr,src._pstr);
		cout<<"String(const String &)"<<endl;
	}
	void operator=(const String &src)//赋值运算符的重载函数
	{
		if (this == &src)//防止发生自赋值
		{
			return ;
		}
		delete[]_pstr;//删除当前对象的_pstr指向的堆空间,防止赋值后找不到此空间发生内存泄漏
		_pstr = new char[strlen(src._pstr)+1];//重新开辟堆内存
		strcpy(_pstr,src._pstr);
		cout<<"operator(const String &)"<<endl;
	}
	void show()
	{
		cout<<"the string is "<<_pstr<<endl;
	}

private:
	char *_pstr;//会发生浅拷贝
};
	 
int main()
{
	String string1=("wangiu");
	string1.show();
	return 0;
}
注意:是否会发生浅拷贝

自定义的拷贝构造函数和赋值运算符的重载函数

题目二:实现Link类

class Link
{
public:
	Link()
	{
		_phead = new Node();//带头节点
	}
	~Link()
	{
		Node *pcur = _phead;
		while(pcur != NULL)
		{
			_phead = _phead->_pnext;
			delete pcur;
			pcur = _phead;
		}
	}
	void insertHead(int val)
	{
		Node *pnode = new Node(val);
		pnode->_pnext = _phead->_pnext;
		_phead->_pnext = pnode;
	}
	void insertTail(int val)
	{
		Node *pnode = new Node(val);
		Node *plast = _phead;
		while(plast->_pnext != NULL)
		{
			plast = plast->_pnext;
		}
		plast->_pnext = pnode;
	}
	void deleteNode(int val)
	{
		Node *ppre = _phead;
		Node *pcur = _phead->_pnext;
		while(pcur != NULL)
		{
			if(val == pcur->_data)
			{
				//删除
				ppre->_pnext = pcur->_pnext;
				delete pcur;
				return;
			}
			ppre = pcur;
			pcur = pcur->_pnext;
		}
	}
	showLink()
	{
		Node *pcur = _phead->_pnext;
		while(pcur != NULL)
		{
			cout<<pcur->_data<<" ";
			pcur = pcur->_pnext;
		}
	}
private:
	class Node
	{
	public:
		Node(int data=0):_data(data),_pnext(NULL){}//初始化列表效率高
		int _data;
		Node *_pnext;

	};//嵌套类 或 内部类
	Node *_phead;
};
嵌套类/初始化列表/

题目三:请给出下面对象创建过程中的方法打印(请注明构造和析构对象的名字) 

class Test
{
public:
    Test(int a=5, int b=5):ma(a), mb(b)
    {
	    cout<<"Test(int)"<<endl;
	}
    ~Test()
    {
	    cout<<"~Test()"<<endl;
	}
    Test(const Test &src):ma(src.ma), mb(src.mb)
    {
	    cout<<"Test(const Test&)"<<endl;
	}
    void operator=(const Test &src)
    {
	    ma = src.ma; 
	    mb = src.mb; 
	    cout<<"operator="<<endl;
	}
private:
    int ma;
    int mb;
};
Test t1(10, 10);
int main()
{
    Test t2(20, 20);
    Test t3=t2;
    static Test t4 = Test(30, 30);
    t2 = Test(40, 40);
    t2 = (Test)(50, 50);
    t2 = 60;
    Test *p1 = new Test(70, 70);
    Test *p2 = new Test[2];
    Test *p3 = &Test(80, 80);
    Test &p4 = Test(90, 90);
    delete p1;
    delete []p2;
}
Test t5(100, 100);

运行结果为:

Test t1(10, 10);//构造t1    
int main()
{
    Test t2(20, 20);//构造t2
    Test t3=t2;//t2拷贝构造t3
    static Test t4 = Test(30, 30);//临时对象拷贝构造同类型对象,相当于直接构造对象,不生成临时对象
    t2 = Test(40, 40);//临时对象(显示生成)  operator=给t2赋值  析构临时对象
    t2 = (Test)(50, 50);//临时对象(显示生成ma=50 mb=5默认值)注意逗号表达式,取最后一个值 operator=给t2赋值  析构临时对象
    t2 = 60;//临时对象 (隐士生成ma=60 mb=5默认值) operator=给t2赋值  析构临时对象
    Test *p1 = new Test(70, 70);//new 构造新对象(70,70)
    Test *p2 = new Test[2];new //构造两个新对象 不能初始化
    Test *p3 = &Test(80, 80);//构造临时对象(80,80) 分号后析构新对象
    Test &p4 = Test(90, 90);//构造临时对象(90,90) 临时对象被引用,生命周期变成引用对象的周期
    delete p1;//析构p1指向的对象
    delete []p2;//两次析构 Test数组中有两个对象
}
Test t5(100, 100);//t5在t1之后构造



4请写出下面程序的打印信息

class Test
{
public:
	Test(int a=5):ma(a)
	{
		cout<<"Test(int)"<<endl;
	}
	~Test()
	{
		cout<<"~Test()"<<endl;
	}
	Test(const Test &src):ma(src.ma)
	{
		cout<<"Test(const Test&)"<<endl;
	}
	Test operator=(const Test &src)//注意返回值是Test,返回时生成一个临时对象
	{
		ma = src.ma;
		cout<<"operator="<<endl;
		return *this;
	}
	int GetValue()
	{
		return ma;
	}
private:
	int ma;
};
Test GetTestObject(Test &t)
{
	int value = t.GetValue();
	Test tmp(value);
	return tmp;
}
int main()
{
		Test t1(20);
	 	Test t2;
		cout<<"************************"<<endl;
	 	//t2.operator=()
	 	t2 = GetTestObject(t1);
	 	cout<<t2.GetValue()<<endl;
	return 0;
}

运行结果:注意operator=的返回值为Test

operator= 返回值为void的结果


5请解释explicit,volatile,mutable三个关键字

explicit

防止隐式对象的生成,修饰构造函数

volatile

防止编译器对指令顺序进行优化

防止在多线程程序中,线程栈缓存共享变量的副本

mutable

在常成员方法里面可以修改普通成员变量的值




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值