首页 > 编程 > C++ > 正文

C++Primer第五版 第十三章习题答案(11~20)

2019-11-06 06:53:26
字体:
来源:转载
供稿:网友

11:构造函数中,分配的动态内存对象,需要delete

 ~Hasptr() { delete ps; }//必须首先delete对象ps,ps指向一个动态分配的string

12:知识点:当指向一个对象的引用或者指针离开作用域是,析构函数并不会执行

析构函数执行三次:accum,item1,item2

13:

#include<iostream>  #include<string>  #include<fstream>#include<list>#include<vector> #include<map>  #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件#include<memory>using namespace std;class A{public:	A(int m):val(m)//默认构造函数	{		cout<<"默认构造函数"<<endl;	}	A& Operator= (const A& a) //拷贝赋值运算符	{		val = a.val;		cout<<"拷贝复制运算符"<<endl;		return *this;	}	~A()//析构函数	{		cout<<"析构函数"<<endl;	}	int val;};void show1(A& a){	cout<<a.val<<endl;}void show2(A a){	cout<<a.val<<endl;}int main(int argc, char**argv)  {	//将A的对象当作引用或者非引用传递	A a(10);	A b(5);	A c(2);	c = a;	show1(a);	show2(b);	show2(c);	//存放于容器中	vector<A> m;	m.push_back(a);	//动态分配	A *d = new A(5);	show2(*d);	delete d;	return 0;}  

14:知识点:这五种操作通常被视为一个整体,一般来说都会一起出现

知识点2:需要析构函数的类也需要拷贝和赋值操作,合成的析构函数不会delete一个指针数据成员,所以有时我们需要自己定义一个析构函数释放构造函数分配的内存,所以需要析构函数的类,也就需要拷贝构造函数和拷贝赋值运算符,而合成的拷贝构造函数和拷贝赋值运算符只能简单的拷贝指针成员,这就意味着多个对象指向同一个内存,释放多个对象时,造成多次delete

知识点3:如果一个类需要自定义版本的析构函数,那么肯定是需要自定义的拷贝构造函数和拷贝赋值运算符

知识点4:拷贝操作和复制操作是相互结合的,如果需要一种,也需要另一种,但不一定意味着需要析构函数

会输出三个一样的数字,合成的拷贝构造函数只是简单的进行拷贝

15:使用了自定义版本的合成构造函数,生成新的序号,那么肯定输出就是三个不一样的数字了

16:函数的参数变为引用版本的形参,无需拷贝,结果改变,但输出仍为三个不一样的数字

17:

#include<iostream>  #include<string>  #include<fstream>#include<list>#include<vector> #include<map>  #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件#include<memory>using namespace std;class A{public:	A()//默认构造函数,14题	{		static int val1 = 10;		val = val1++;	}	A(A &a)//自定义版本的拷贝构造函数	{		val = a.val+5;	}	int val;};void show2(A a){	cout<<a.val<<endl;}void show3(const A& a){	cout<<a.val<<endl;}int main(int argc, char**argv)  {	A a, b = a, c = b;	show2(a);//调用函数时需要拷贝一次	show2(b);	show2(c);// 	show3(a);//这里的调用不需要拷贝构造运算符// 	show3(b);// 	show3(c);	return 0;}  

18:知识点1:我们可以通过将拷贝控制成员定义为 =default 来显式的要求编译器生成合成的版本(只能对有合成版本的函数使用),在此之后,合成的函数将隐式的声明为内联

知识点2:iostream类阻止了拷贝,避免多个对象同时写入,或读取相同的IO缓冲,我们可以将拷贝构造函数和拷贝赋值运算符定义为删除的函数来阻止拷贝,虽然声明了他们,但不能以任何的方式使用他们,在参数列表之后加上 =delete 来指出我们希望其是被删除的,这是为了通知编译器,我们不希望这些函数被定义

知识点3:可以对任何类内函数(析构函数除外)声明 =delete ,且必须出现在函数第一次声明的时候,如果析构函数被声明=delete ,析构函数被删除,就无法销毁此类型的对象

知识点4:本质上,当不可能拷贝、赋值、销毁类的成员时,类的拷贝构造函数会被定义为删除的

知识点5:C++11之前,是将拷贝构造函数和拷贝赋值运算符定义为PRivate来阻止拷贝的(旧标准)

见下方19题:

19:拷贝控制成员:拷贝构造函数和拷贝赋值运算符

#include<iostream>  #include<string>  #include<fstream>#include<list>#include<vector> #include<map>  #include<set>#include<cctype>//ctype无法打开,包含tolower()函数和ispunct函数#include<algorithm>#include<utility>//保存pair的头文件#include<memory>using namespace std;//具体操作时将类的声明置于头文件中class Employee{public:	Employee();//默认构造函数	Employee(string& s);//接受一个string的构造函数		Employee(const Employee&) =delete;//不需要拷贝构造函数,怎么可能有人一样。将其声明为 =delete	Employee& operator= (const Employee&) =delete;	int number(){return _number;}private:	string employee;	int _number;	static int O_number;//static静态成员数据在类内声明,但只可以在类外定义,在类外定义时可不加static};int Employee::O_number = 0;Employee::Employee()//默认构造函数{	_number = O_number++;}Employee::Employee(string& s)//接受一个string的构造函数{	employee = s;	_number = O_number++;}void show(Employee a){	cout<<a.number()<<endl;}int main(int argc, char**argv)  {	Employee a, b, c;	show(a);//调用函数时需要拷贝一次	show(b);	show(c);	return 0;} 

20:

TextQuery和QueryResult所有成员(包括智能指针和容器)都将被拷贝 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选