设为首页 加入收藏

TOP

C++ - 类似"vector"容器(存储string) 的 实现
2015-11-21 01:55:10 来源: 作者: 【 】 浏览:4
Tags:类似 " vector" 容器 存储 string 实现
类似"vector"容器(存储string) 的 实现
?
类似vector容器, 实现存储string类型, 需要预先分配内存, 然后根据添加元素的多少, 动态的增加内存(alloc_n_copy), 使用库函数"allocator<>"容器去管理内存.
新旧元素的赋值, 使用库函数move()去实现; 并且重写了copy构造器, copy-assignment构造器, destructor.
注意实现的每一个函数和"allocator<>"的使用; reallocate: 重新分配内存; free: 释放内存;
代码 (Eclipse CDT; GCC 4.7.1):
?
/* 
 * CppPrimer.cpp 
 * 
 *  Created on: 2013.11.7 
 *      Author: Caroline 
 */  
  
#include   
#include   
#include   
#include   
#include   
#include   
  
class StrVec {  
public:  
    StrVec () : elements (nullptr), first_free (nullptr), cap (nullptr) {}  
    StrVec (const StrVec&);  
    StrVec &operator= (const StrVec&);  
    ~StrVec();  
    void push_back (const std::string &);  
    size_t size () const { return first_free-elements; }  
    size_t capacity () const { return cap-elements; }  
    std::string *begin() const { return elements; }  
    std::string *end() const { return first_free; }  
private:  
    static std::allocator alloc;  
    void free();  
    void reallocate();  
    void chk_n_alloc () {  
        if(size() == capacity())  
            reallocate();  
    }  
    std::pair alloc_n_copy  
    (const std::string*, const std::string*);  
    std::string *elements;  
    std::string *first_free;  
    std::string *cap;  
};  
void StrVec::reallocate () {  
    auto newcapacity = size() ? 2*size() : 1; //正常2倍, 为空分配一个  
    auto newdata = alloc.allocate(newcapacity);  
    auto dest = newdata;  
    auto elem = elements;  
    for (std::size_t i=0; i!=size(); ++i)  
        alloc.construct(dest++, std::move(*elem++)); //每个元素均移动  
    free();  
    elements = newdata;  
    first_free = dest;  
    cap = elements + newcapacity;  
}  
  
std::allocator StrVec::alloc; //需要初始化  
  
void StrVec::push_back(const std::string& s)  
{  
    chk_n_alloc ();  
    alloc.construct(first_free++, s); //注意后++  
}  
std::pair  
StrVec::alloc_n_copy(const std::string *b, const std::string *e)  
{  
    auto data = alloc.allocate(e-b); //分配足够的空间  
    return {data, std::uninitialized_copy(b, e, data)}; //把数据存入空间, 返回首尾指针  
}  
void StrVec::free ()  
{  
    if (elements) {  
        for (auto p=first_free; p!=elements;)  
            alloc.destroy(--p); //先--, 指向确定元素  
        alloc.deallocate(elements, cap-elements); //释放内存, 首元素和内存大小  
    }  
}  
StrVec::StrVec (const StrVec &s)  
{  
    auto newdata = alloc_n_copy(s.begin(), s.end()); //pair类型  
    elements = newdata.first;  
    first_free = cap = newdata.second;  
}  
StrVec::~StrVec() { free(); }  
StrVec &StrVec::operator= (const StrVec &rhs)  
{  
    auto data = alloc_n_copy(rhs.begin(), rhs.end());  
    free ();  
    elements = data.first;  
    first_free = cap = data.second;  
    return *this;  
}  
int main (void) {  
    StrVec sv;  
    sv.push_back("Girls");  
    sv.push_back("Ladies");  
    sv.push_back("Women");  
    for(auto it = sv.begin(); it != sv.end(); ++it)  
        std::cout << *it << " ";  
    std::cout << std::endl;  
    return 0;  
}  

?

?
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU2368:Alfredo's Pizza Re.. 下一篇10277 Boastin' Red Socks(概..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: