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

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

2019-11-06 07:22:49
字体:
来源:转载
供稿:网友

11:知识点1:理解变量的销毁与其内存的释放之间的关系:内置类型的指针在离开作用域时,本身会被销毁,但是其指向的内存空间什么都不会发生,必须以显式的delete进行释放空间。智能指针在离开作用域时,本身也会被销毁,并且计数器减一,当其计数器为0且只有一个智能指针指向该对象时,该对象的内存空间会被释放。如若用智能指针的get()函数得到的一个内置指针来初始化一个临时的智能指针,一旦该内置指针被释放,指向的内存也会被释放,原来的智能指针就会变成空指针

知识点2:永远不要用get初始化另一个智能指针或是给智能指针赋值

此题:利用P的get()函数得到的内置指针来初始化一个临时的智能指针,一旦调用结束,该临时指针被销毁,内置指针所指对象内存会被释放,使得p变为空悬指针

12:知识点1:将一个新的指针赋给shared_ptr:利用reset()函数,会更新计数。

此题:p为普通的内置指针指向一个动态内存,sp为智能指针指向一个动态内存

(a):合法,处理sp指针所指向内容,赋值的方式传递参数,处理完毕后内存不会被释放

(b):不合法,参数必须是智能指针int类型

(c):同上

(d):合法,处理完毕后内存会被释放

13:删除p之后,会导致p指向的内存被释放,此时sp就会变成空悬指针,在sp指针被销毁时,该块内存会被二次delete,执行后产生错误:double free

14:知识点1:如果在new和delete之间发生了异常,且异常未被捕获,则该内存就永远不会被释放!(非常危险!!!),而智能指针只要离开作用域,计数器减一,则随着智能指针被销毁,该块内存也会被释放,这就说明在实际使用过程中应使用shared_ptr来防止内存泄漏

知识点2:正确的使用智能指针:

1:不使用相同的内置指针值初始化多个智能指针

2:不delete get()返回的指针

3:不使用get()初始化或reset另一个只能指针

4:当你使用的智能指针管理的资源布氏new分配的内存,记住传递一个删除器

15:直接将删除器函数修改即可

[](connection *p){ disconnect *p; }

16:知识点1:unique_ptr拥有其所指向的对象,属于一一对应关系,unique_ptr被销毁时,其对象也会被销毁,unique_ptr不支持拷贝和赋值,必须采用直接初始化的方式,当我们定义一个unique_ptr时,必须将其绑定到一个new返回的指针上

知识点2:可以使用release():放弃对指针的控制权,返回指针,并将其置为空,和reset():如果提供了内置指针q,令u指向这个对象,否则将u置空,将指针的所有权转移,但并没有释放内存

知识点3:在unique_ptr快要被销毁时,可以进行拷贝:返回unique_ptr指针,这是一种特殊的拷贝P473页

出现的问题:一一对应的关系,其指向的对象是其类的私有成员

 error C2248: “std::unique_ptr<_Ty>::unique_ptr”: 无法访问 PRivate 成员(在“std::unique_ptr<_Ty>”类中声明)

17:

(a):不合法,ix不是new返回的指针

(b):同上

(c):不合法,unique_ptr必须采用直接初始化

(d):不合法,同(a)

(e):合法

(f):合法,但是p5被销毁后,p2所指向的内存也会被销毁,使得p2成为空悬指针

18:release()函数的作用就是放弃对指针指向对象的控制权,但shared_ptr是多对一的关系,其他的智能指针仍然可以删除这个对象,所以这个函数的话对shared_ptr没意义

19:知识点1:weak_ptr:不控制所指向对象生命周期的智能指针,使用时必须进行判断对象是否存在

shared_ptr<int> u(new int(1024));weak_ptr<int> w_ptr(u);if (shared_ptr<int> u = w_ptr.lock()){	//....}

若weak_ptr指向的内容存在,则lock()返回一个指向共享对象的shared_ptr,若无,则返回空shared_ptr

这样的类定义应该放在头文件中

class StrBlob{public:	friend class StrBlobPtr;//声明friend	StrBlobPtr begin();	StrBlobPtr end();	StrBlob();//默认构造函数	StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}///C++11新特性	StrBlob(string il):data(make_shared<vector<string>> (il)){}//另一构造函数	typedef vector<string>::size_type size_type;//定义类型别名,方便使用	//定义函数,返回大小	size_type size() const	{		return data->size();	}	//判断vector<string>是否为空	bool empty()	{		return data->empty();	}	//向vector<string>中加入元素	void pushback(const string &s)	{		data->push_back(s);	}	//访问函数,应首先调用check()	string& front()	{		check(0,"front on empty StrBlob");		return data->front();	}	string& back()	{		check(0,"back on empty StrBlob");		return data->back();	}	void popback()	{		check(0,"pop_back on empty StrBlob");		data->pop_back();	}private:	shared_ptr<vector<string>> data;//指向vector<string>的智能指针	void check(size_type i,const string &msg) const//若访问元素的大小大于data的size,输出错误信息	{		if (i > data->size())		{			throw out_of_range(msg);//抛出该out_of_range异常,表示不在范围之内		}	}};class StrBlobPtr{public:	StrBlobPtr():curr(0){}//构造函数,将curr设定为0	StrBlobPtr(StrBlob &a, size_t sz = 0):wptr(a.data),curr(sz){}//构造函数,将StrBlob的智能指针与此类中的weak_ptr绑定	string& deref() const	{		auto p =check(curr,"deference past end");		return (*p)[curr];	}	StrBlobPtr& incr()	{		auto p =check(curr,"deference past end");		++curr;		return *this;	}private:	shared_ptr<vector<string>> check(size_t i,const string& msg) const//检查函数,返回一个vector<string>的智能指针	{		auto ret = wptr.lock();//检查对象是否还存在		if(!ret)		{			throw runtime_error("未绑定");		}		if (i >= ret->size())		{			throw out_of_range(msg);		}		return ret;	}	weak_ptr<vector<string>> wptr;//定义弱智能指针	size_t curr;//设立游标,表示下标};StrBlobPtr StrBlob::begin(){	return StrBlobPtr(*this);}StrBlobPtr StrBlob::end(){	return StrBlobPtr(*this, data->size());}

20:

#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<Chapter12.h>using namespace std;int main(int argc, char**argv)  { 	ifstream in("1.txt");	string s;	StrBlob blob;	while (getline(in,s))	{		blob.pushback(s);	}	for (StrBlobPtr pbeg(blob.begin()), pend(blob.end()); pbeg != pend;		pbeg.incr())		cout << pbeg.deref() << std::endl;	return 0;}  


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

图片精选