zoukankan      html  css  js  c++  java
  • 【C++ Primer 第13章】5. 动态内存管理类

    StrVec类的设计

    【题目描述】:我们将实现标准库vector类的一个简化版本,我们所做的一个简化是不使用模板,我们类只用于string,因此,它被命名为StrVec。

      1 #include<iostream>
      2 #include<string>
      3 #include<memory>
      4 using namespace std;
      5 
      6 class StrVec {
      7 public:
      8     StrVec(): elements(nullptr), first_free(nullptr), cap(nullptr) {}
      9     StrVec(const StrVec &);
     10     StrVec& operator=(const StrVec&);
     11     ~StrVec() { free(); };
     12 
     13     StrVec(StrVec &&s) noexcept;
     14     StrVec& opearator=(StrVec &&rhs) noexcept;
     15 
     16     void push_back (const string&);
     17     size_t size() const       { return first_free - elements; }
     18     size_t capacity() const   { return cap - elements; }
     19     string *begin() const     { return elements; }
     20     string *end() const       { return first_free; }
     21 
     22 private:
     23     static allocator<string> alloc;
     24     void chk_n_alloc() { if (size() == capacity()) reallocate(); }
     25     pair<string*, string*> alloc_n_copy(const string*, const string *);
     26     void free();
     27     void reallocate();
     28     string *elements;    //指向数组首元素的指针
     29     string *first_free;  //指向数组第一个空闲元素的指针
     30     string *cap;         //指向数组尾后位置的指针
     31 };
     32 
     33 StrVec::StrVec(const StrVec &s)
     34 {
     35     auto newdata = alloc_n_copy(s.begin(), s.end());
     36     elements = newdata.first;
     37     first_free = cap = newdata.second;
     38 }
     39 
     40 StrVec& StrVec::operator=(const StrVec &rhs)
     41 {
     42     auto data = alloc_n_copy(rhs.begin(), rhs.end());
     43     free();
     44     elements = data.first;
     45     first_free = cap = newdata.second;
     46     return *this;
     47 }
     48 
     49 void StrVec::free()
     50 {
     51     if (elements)
     52     {
     53         for (auto p = first_free; p != elements; )
     54             alloc.destroy(--p);
     55         alloc.deallocate(elements, cap - elements);
     56     }
     57 }
     58 
     59 pair<string *, string *> StrVec::alloc_n_copy(const string *b, const string *e)
     60 {
     61     auto data = alloc.allocate(e - b);
     62     return { data, uninitialized_copy(b, e, data) };
     63 }
     64 
     65 void StrVec::push_back(const string& s)
     66 {
     67     chk_n_alloc();
     68     alloc.construct(first_free++, s);
     69 }
     70 
     71 void StrVec::reallocate()
     72 {
     73     auto newcapacity = size() ? 2 * size() : 1;
     74     auto newdata = alloc.allocate(newcapacity);
     75     auto dest = newdata;
     76     auto elem = elements;  //原对象的elements指针
     77     for (size_t i = 0; i != size(); ++i)
     78         alloc.construct(dest++, std::move(*elem++));
     79     free();
     80     elements = newdata;
     81     first_free = dest;
     82     cap = elements + newcapacity;
     83 }
     84 
     85 StrVec::StrVec(StrVec &&s) noexcept
     86 : elements(s.elements), first_free(s.first_free), cap(s.cap)
     87 {
     88     s.elements = s.first_free = cap = nulllptr;
     89 }
     90 
     91 StrVec& StrVec::StrVec(StrVec &&s) noexcept
     92 {
     93     if (this = &s)
     94     {
     95         free();
     96         elemens = rhs.elements;
     97         first_free = .frhsirst_free;
     98         cap = rhs.cap;
     99         rhs.elements = srhs.first_free = rhs.cap = nullptr;
    100     }
    101     return *this;
    102 }

     3.5节练习

    • 编写标准库string类的简化版本,命名为string。

      1 #include<iostream>
      2 #include<memory>
      3 #include<cstring>
      4 #include<initializer_list>
      5 using namespace std;
      6 
      7 class String {
      8     friend String operator+(const String&, const String&);
      9     friend String add(const String&, const String&);
     10     friend ostream &operator<<(std::ostream&, const String&);
     11     friend ostream &print(std::ostream&, const String&);
     12     
     13 public:
     14     String():sz(0), p(nullptr) {}; 
     15     String(const char *cp): sz(strlen(cp)), p(p.allocate(sz)) { uninitialized_copy(cp, cp + sz, p)}
     16     String(const String &s): sz(s.sz), p(a.allocate(sz)) { uninitialized_copy(s.p, s.p + sz, p)}
     17     String(size_t n, char c): sz(n), p(a.allocate(n)) {uninitialized_fill_n(p, n, t)}
     18     ~String() noexcept { if (p) a.deallocate(p, sz); }
     19 
     20     String &operator=(const String &);
     21     String &operator=(const char*);        
     22     String &operator=(char); 
     23     String &operator=(initializer_list<char>);
     24 
     25 
     26     const char *begin()         { return p; }
     27     const char *begin() const   { return p; }
     28     const char *end()           { return p + sz; }
     29     const char *end() const     { return p + sz; }
     30     size_t size() const         { return sz; }
     31     void swap(String &s);
     32 
     33 private:
     34     static allocator<char> a;
     35     size_t sz;
     36     char *p;
     37 };
     38 
     39 /***********************************************************************************/
     40 ostream &operator<<(ostream &os, const string &s)
     41 {
     42     return print(os, rhs);
     43 }
     44 
     45 ostream &print(ostream &os, const string &s)
     46 {
     47     auto p = s.begin();
     48     while(p != s.end())
     49         os << *p++;
     50     return os;
     51 }
     52 
     53 string add(const string &lhs, const string &rhs)
     54 {
     55     string ret;
     56     ret.sz = lhs.size() + rhs.size();
     57     ret.p = a.allocate(ret.sz);
     58     uninitialized_copy(lhs.begin(), lhs.end(),ret.p);
     59     uninitialized_copy(rhs.begin(), rhs.end(), ret.p + lhs.sz);
     60     return ret;
     61 }
     62 
     63 string operator+(const string &lhs, const string &rhs)
     64 {
     65     return add(lhs, rhs);
     66 }
     67 /************************************************************************************/
     68 
     69 String &String::operator=(const String &rhs)
     70 {
     71     auto newp = a.allocator(rhs.sz);
     72     uninitlized_copy(rhs.p, rhs.p + rhs.ze, newp);
     73     if (p)
     74         a.deallocate(p, sz);
     75     p = newp;
     76     sz = rhs.sz;
     77     return *this;
     78 }
     79 
     80 String &String::operator=(const char *cp)
     81 {
     82     if(p)
     83         a.deallocate(p, sz);
     84     p = a.allocate(sz = strlen(cp));
     85     uninitialzied_copy(cp, cp + sz, p);
     86     return *this;
     87 }
     88 
     89 String &String::operator=(char c)
     90 {
     91     if(p)
     92         a.deallocate(p, sz);
     93     p = a.allocate(sz = 1);
     94     *p = c;
     95     return *this;
     96 }
     97 
     98 String& string::operator=(initializer_list<char> il)
     99 {
    100     if(p)
    101         a.deallocate(p, sz);
    102     p = a.llocate(il.size());
    103     uninitialized_copy(il.begin(), il.end(), p);
    104     return *this;
    105 }
    106 
    107 /***************************************************************************************/
    108 
    109 void string::swap(String &s)
    110 { 
    111     auto tmp = p; 
    112     p = s.p; 
    113     s.p = tmp; 
    114     auto cnt = sz;
    115     sz = s.sz; 
    116     s.sz = cnt; 
    117 }
    118 
    119 void swap(String &s1, String &s2)
    120 {
    121     s1.swap(s2);
    122 
    123 
    124 String make_plural(size_t ctr, const String &, const String &)
    125 {
    126         return (ctr != 1) ?  add(word, ending) : word;
    127 }
  • 相关阅读:
    某个牛人做WINDOWS系统文件详解
    常用ASP脚本程序集锦
    LINUX基础:文件安全与权限
    proftpd+mysql+quota
    apache2.0.49tomcat5.0.19jk2建立virtualHost
    URL Redirection(转) Anny
    顶级域名后缀列表(转) Anny
    \u4E00\u9FA5意义 Anny
    How to POST Form Data Using Ruby(转) Anny
    How to get rid of 'Enter password to unlock your login keyring' in Ubuntu(转) Anny
  • 原文地址:https://www.cnblogs.com/sunbines/p/9012501.html
Copyright © 2011-2022 走看看