码迷,mamicode.com
首页 > 编程语言 > 详细

C++primer 13.2.1节练习

时间:2017-09-01 21:21:03      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:悬空指针   fst   str1   time   print   error   分配   有一个   通过   

练习13.23

 1 #include <iostream>
 2 #include <string>
 3 #include <memory>
 4 
 5 using namespace std;
 6 
 7 
 8 class HasPtr {
 9     friend ostream &print(ostream &os, HasPtr &h);
10 public:
11     HasPtr(const string &s = string()) : ps(new string(s)), i(0) {}
12     HasPtr(const HasPtr &ptr);
13     HasPtr &operator=(const HasPtr &pt);
14     ~HasPtr() { }
15 private:
16     string *ps;
17     int i;
18 };
19 
20 ostream &print(ostream &os, HasPtr &h);
21 
22 int main()
23 {
24     HasPtr has("hello");
25     HasPtr have = has;
26     print(cout, have);
27     system("pause");
28     return 0;
29 }
30 
31 HasPtr::HasPtr(const HasPtr & ptr) : ps(new string(*ptr.ps)), i(ptr.i) {}
32 
33 HasPtr & HasPtr::operator=(const HasPtr & pt)
34 {
35     auto newp = new string(*pt.ps);
36     delete ps;
37     ps = newp;
38     i = pt.i;
39     return *this;
40     // TODO: 在此处插入 return 语句
41 }
42 
43 ostream & print(ostream & os, HasPtr & h)
44 {
45     os << h.ps << h.i << endl;
46     return os;
47     // TODO: 在此处插入 return 语句
48 }

练习13.24

1. 如果没有定义析构函数的话,会造成内存泄露。因为,成员变量ps是通过new操作在堆上显式分配出的一段内存,需要使用delete显式的去释放。

2. 如果没有定义拷贝构造函数的话,可能会造成二次释放,或使用悬空指针的情况。因为,在合成的赋值运算符中,让不同实例的ps指向同一段内存的起始位置。当其中有一个实例对内存进行释放或其他操作时,别的实例也会受到印象,如果只是修改值之类的操作,影响并不是很大(不至于崩溃);但是,当有释放的操作时,程序很可能会发生崩溃。

练习13.25

拷贝构造函数和拷贝赋值运算符需要做的就是分配一个新的内存并赋予其值然后进行拷贝,不需要析构函数是因为智能指针自己有析构函数进行内存的释放;

练习13.26

  1 #include <iostream>
  2 #include <fstream>
  3 #include <string>
  4 #include <sstream>
  5 #include <set>
  6 #include <map>
  7 #include <algorithm>
  8 #include <vector>
  9 #include <algorithm>
 10 #include <iterator>
 11 #include <unordered_map>
 12 #include <memory>
 13 
 14 using namespace std;
 15 
 16 class strBlobPtr;
 17 class strBlob {
 18     friend void print(strBlob s);
 19     friend class strBlobPtr;
 20 public:
 21     typedef vector<string>::size_type size_type;
 22     strBlob();
 23     strBlob(initializer_list<string> il);
 24     strBlob(const strBlob& str) : data(make_shared<vector<string>>(*str.data)) {}        //拷贝构造函数
 25     strBlob &operator=(const strBlob &str);                                                //拷贝赋值运算符
 26     size_type size() const { return data->size(); }
 27     bool empty() const { return data->empty(); }
 28     void push_back(const string &t);
 29     void pop_back();
 30     const string &front();
 31     const string &back();
 32     strBlobPtr begin();
 33     strBlobPtr end();
 34 private:
 35     shared_ptr<vector<string>> data;
 36     void check(size_type i, const string &msg) const;
 37 };
 38 
 39 class strBlobPtr {
 40 public:
 41     strBlobPtr() : curr(0) {}
 42     strBlobPtr(strBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
 43     string & deref() const;
 44     strBlobPtr &incr();
 45 private:
 46     shared_ptr<vector<string>> check(size_t t, const string &str) const;
 47     weak_ptr<vector<string>> wptr;
 48     size_t curr;
 49 };
 50 
 51 void print(strBlob s);
 52 
 53 int main()
 54 {
 55     strBlob p1({ "asd", "qew", "jkl" });
 56     print(p1);
 57     p1.push_back("dqw");
 58     print(p1);
 59     p1.pop_back();
 60     p1.pop_back();
 61     print(p1);
 62     cout << endl;
 63     cout << p1.front() << endl;
 64     cout << p1.back() << endl;
 65     system("pause");
 66     return 0;
 67 }
 68 
 69 strBlob::strBlob() : data(make_shared<vector<string>>()) {}
 70 strBlob::strBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
 71 
 72 strBlob & strBlob::operator=(const strBlob & str)
 73 {
 74     auto str1 = make_shared<vector<string>>(*str.data);
 75     data = str1;
 76     return *this;
 77     // TODO: 在此处插入 return 语句
 78 }
 79 
 80 void strBlob::push_back(const string & t)
 81 {
 82     data->push_back(t);
 83 }
 84 void strBlob::pop_back()
 85 {
 86     check(0, "pop_back on empty StrBlob");
 87     data->pop_back();
 88 }
 89 const string & strBlob::front()
 90 {
 91     check(0, "front on empty StrBlob");
 92     return data->front();
 93     // TODO: 在此处插入 return 语句
 94 }
 95 const string & strBlob::back()
 96 {
 97     check(0, "back on empty StrBlob");
 98     return data->back();
 99     // TODO: 在此处插入 return 语句
100 }
101 
102 strBlobPtr strBlob::begin()
103 {
104     return strBlobPtr(*this);
105 }
106 
107 strBlobPtr strBlob::end()
108 {
109     return strBlobPtr(*this, data->size());
110 }
111 
112 
113 void strBlob::check(size_type i, const string & msg) const
114 {
115     if (i >= data->size())
116         throw out_of_range(msg);
117 }
118 
119 void print(strBlob s)
120 {
121     for (auto c : *(s.data))
122         cout << c << endl;
123     cout << endl;
124 }
125 
126 string & strBlobPtr::deref() const
127 {
128     auto p = check(curr, "dereference past end");
129     return (*p)[curr];
130     // TODO: 在此处插入 return 语句
131 }
132 
133 strBlobPtr & strBlobPtr::incr()
134 {
135     check(curr, "increment past end of strBlobPtr");
136     ++curr;
137     return *this;
138     // TODO: 在此处插入 return 语句
139 }
140 
141 shared_ptr<vector<string>> strBlobPtr::check(size_t t, const string & str) const
142 {
143     auto ret = wptr.lock();
144     if (!ret)
145         throw runtime_error("unbound strBlobPtr");
146     if (t >= ret->size())
147         throw out_of_range(str);
148     return ret;
149 }

 

C++primer 13.2.1节练习

标签:悬空指针   fst   str1   time   print   error   分配   有一个   通过   

原文地址:http://www.cnblogs.com/wuyinfenghappy/p/7464981.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!