zoukankan      html  css  js  c++  java
  • C++Primer第五版——习题答案详解(十一)


    习题答案目录:https://www.cnblogs.com/Mered1th/p/10485695.html

    第12章 动态内存


    练习12.1
    b1包含4个元素,b2被销毁

    练习12.2

    #include <string>
    #include <initializer_list>
    #include <memory>
    #include <vector>
    #include <stdexcept>
    
    class StrBlob
    {
    public:
    	typedef std::vector<std::string>::size_type size_type;
    	StrBlob();
    	StrBlob(std::initializer_list<std::string> il);
    	size_type size() const { return data->size(); }
    	bool empty() const { return data->empty(); }
    	void push_back(const std::string &t) { data->push_back(t); }
    	void pop_back();
    	std::string& front();
    	std::string& back();
    	const std::string& front() const;
    	const std::string& back() const;
    private:
    	std::shared_ptr<std::vector<std::string>> data;
    	void check(size_type i, const std::string &msg) const;
    };
    
    StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
    StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {}
    
    void StrBlob::check(size_type i, const std::string &msg) const
    {
    	if (i >= data->size())
    		throw std::out_of_range(msg);
    }
    
    std::string& StrBlob::front()
    {
    	check(0, "front on empty StrBlob");
    	return data->front();
    }
    
    std::string& StrBlob::back()
    {
    	check(0, "back on empty StrBlob");
    	return data->back();
    }
    
    const std::string& StrBlob::front() const
    {
    	check(0, "front on empty StrBlob");
    	return data->front();
    }
    
    const std::string& StrBlob::back() const
    {
    	check(0, "back on empty StrBlob");
    	return data->back();
    }
    
    void StrBlob::pop_back()
    {
    	check(0, "pop_back on empty StrBlob");
    	data->pop_back();
    }
    

    练习12.6

    #include<vector>
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    vector<int> *create_vi() {
    	return new std::vector<int>;
    }
    
    void push_vi(vector<int> *p) {
    	int i;
    	while (cin >> i) {
    		p->push_back(i);
    	}
    }
    
    void print_vi(vector<int> *p) {
    	for (const auto i : (*p)) {
    		cout << i << " ";
    	}
    	cout << endl;
    }
    
    int main() {
    	auto p = create_vi();
    	push_vi(p);
    	print_vi(p);
    	delete(p);
    	system("pause");
    	return 0;
    }
    

    练习12.7

    #include<vector>
    #include<iostream>
    #include<string>
    #include<memory>
    
    using namespace std;
    
    shared_ptr<vector<int>> create_vi() {
    	return make_shared<vector<int>>();
    }
    
    void push_vi(shared_ptr<vector<int>> p) {
    	int i;
    	while (cin >> i) {
    		p->push_back(i);
    	}
    }
    
    void print_vi(shared_ptr<vector<int>> p) {
    	for (const auto i : (*p)) {
    		cout << i << " ";
    	}
    	cout << endl;
    }
    
    int main() {
    	auto p = create_vi();
    	push_vi(p);
    	print_vi(p);
    	system("pause");
    	return 0;
    }
    

    练习12.8
    有,p的类型被强制转换为bool值,并且new的内存没有delete。

    练习12.9
    r=q后r所指的内存没有释放,再使用p指针会出错。

    练习12.10
    正确

    练习12.11
    离开process时,p指向的内存会被释放,再使用p指针会出现错误。

    练习12.12
    a.合法,将智能指针赋值给process
    b.不合法,shared_ptr初始化内置指针时需要使用直接初始化的形式。
    c.不合法,shared_ptr初始化内置指针时需要使用直接初始化的形式。
    d.合法。

    练习12.13
    sp和p指向同一个内存,释放了p所指的内存后,再使用sp调用对象可能会出错。

    练习12.14

    #include<iostream>
    #include<memory>
    #include<string>
    
    using namespace std;
    
    struct destination {
    	string des;
    	destination(string des_) :des(des_) {}
    };
    
    struct connection{
    	string conn;
    	connection(string conn_) :conn(conn_) {}
    };
    
    connection connect(destination *des_) {
    	cout << "connect to: " << des_->des << endl;
    	return connection(des_->des);
    }
    
    void disconnect(connection conn_) {
    	cout << "disconnect " << conn_.conn << endl;
    }
    
    void end_connection(connection *p) { disconnect(*p); }
    
    void f(destination &d) {
    	connection c = connect(&d);
    	shared_ptr<connection> p(&c, end_connection);  //p接管了内置指针&c所指向的对象的所有权
    	cout << "connecting now(" << p.use_count() << ")" << endl;
    }
    
    int main() {
    	destination des("aa");
    	f(des);
    
    	system("pause");
    	return 0;
    }
    

    练习12.15

    #include<iostream>
    #include<memory>
    #include<string>
    
    using namespace std;
    
    struct destination {
    	string des;
    	destination(string des_) :des(des_) {}
    };
    
    struct connection{
    	string conn;
    	connection(string conn_) :conn(conn_) {}
    };
    
    connection connect(destination *des_) {
    	cout << "connect to: " << des_->des << endl;
    	return connection(des_->des);
    }
    
    void disconnect(connection conn_) {
    	cout << "disconnect " << conn_.conn << endl;
    }
    
    void end_connection(connection *p) { disconnect(*p); }
    
    void f(destination &d) {
    	connection c = connect(&d);
    	shared_ptr<connection> p(&c, [](connection *p) {disconnect(*p);});  //p接管了内置指针&c所指向的对象的所有权
    	cout << "connecting now(" << p.use_count() << ")" << endl;
    }
    
    int main() {
    	destination des("aa");
    	f(des);
    
    	system("pause");
    	return 0;
    }
    

    练习12.16

    #include<iostream>
    #include<memory>
    using namespace std;
    
    int main() {
    	unique_ptr<string> p1(new string("Stegosaurus"));
    	//unique_ptr<string> p2 = p1;
    	//unique_ptr<string> p3(p1);
    	system("pause");
    	return 0;
    }
    

    尝试引用已删除的函数

    练习12.17

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

    (b)不合法,pi不是new返回的指针

    (c)合法

    (d)不合法,&ix不是new返回的指针

    (e)合法

    (f)不合法,必须使用new返回的指针进行初始化,赋值和拷贝的操作也不包含get()方法

    练习12.18

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

    练习12.19

    class StrBlob
    {
    public:
    	friend class StrBlobPtr;//声明friend
    	StrBlobPtr begin();
    	StrBlobPtr end();
    	StrBlob();//默认构造函数
    	StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}
    	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());
    }
    

    练习12.23

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
    	const char a[] = "aaa";
    	const char b[] = "bbb";
    	char *ans = new char[strlen(a) + strlen(b) + 1];
    	strcpy(ans, a);
    	strcat(ans, b);
    	cout << string(ans) << endl;
    	delete[] ans;
    	system("pause");
    	return 0;
    }
    
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main() {
    	const string a = "aaa";
    	const string b = "bbb";
    	cout << a + b << endl;
    	system("pause");
    	return 0;
    }
    

    练习12.24

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main() {
    	string s;
    	cin >> s;
    	char *t = new char[s.size() + 1];
    	strcpy(t, s.c_str());
    	cout << t << endl;
    	delete[] t;
    	system("pause");
    	return 0;
    }
    

    练习12.25

    delete[] pa;
    

    练习12.26

    #include<iostream>
    #include<memory>
    #include<string>	
    
    using namespace std;
    int main() {
    	allocator<string> alloc;
    	auto const p = alloc.allocate(10);
    	string s;
    	auto q = p;
    	while (cin >> s && q != p + 10) {
    		alloc.construct(q++, s);
    	}
    	while (q!=p)
    	{
    		alloc.destroy(--q);
    	}
    	alloc.deallocate(p, 100);
    
    	system("pause");
    	return 0;
    }
    
  • 相关阅读:
    Hdu 1257 最少拦截系统
    Hdu 1404 Digital Deletions
    Hdu 1079 Calendar Game
    Hdu 1158 Employment Planning(DP)
    Hdu 1116 Play on Words
    Hdu 1258 Sum It Up
    Hdu 1175 连连看(DFS)
    Hdu 3635 Dragon Balls (并查集)
    Hdu 1829 A Bug's Life
    Hdu 1181 变形课
  • 原文地址:https://www.cnblogs.com/Mered1th/p/10585550.html
Copyright © 2011-2022 走看看