【足迹C++primer】47、Moving Objects(2)
来源:互联网 发布:linux alias ll 编辑:程序博客网 时间:2024/06/14 06:32
Moving Objects(2)
Rvalue References and Member Functions
StrVec.h
#ifndef STRVEC_H#define STRVEC_H#include <iostream>#include <memory>#include <utility>// simplified implementation of the memory allocation strategy for a vector-like classclass StrVec {public:// copy control members StrVec(): elements(0), first_free(0), cap(0) { }StrVec(const StrVec&); // copy constructorStrVec &operator=(const StrVec&); // copy assignment~StrVec(); // destructor// additional constructorStrVec(const std::string*, const std::string*); void push_back(const std::string&); // copy the element void push_back(std::string&&); //move the element// add elements size_t size() const { return first_free - elements; } size_t capacity() const { return cap - elements; }// iterator interfacestd::string *begin() const { return elements; }std::string *end() const { return first_free; }// operator functions covered in chapter 14std::string& operator[](std::size_t n){ return elements[n]; }const std::string& operator[](std::size_t n) const{ return elements[n]; }private: static std::allocator<std::string> alloc; // allocates the elements// utility functions:// used by members that add elements to the StrVecvoid chk_n_alloc(){ if (size() == capacity()) reallocate(); } // used by the copy constructor, assignment operator, and destructorstd::pair<std::string*, std::string*> alloc_n_copy (const std::string*, const std::string*);void free(); // destroy the elements and free the space void reallocate(); // get more space and copy the existing elements std::string *elements; // pointer to the first element in the array std::string *first_free; // pointer to the first free element in the array std::string *cap; // pointer to one past the end of the array};#include <algorithm>inlineStrVec::~StrVec() { free(); }inlinestd::pair<std::string*, std::string*>StrVec::alloc_n_copy(const std::string *b, const std::string *e){// allocate space to hold as many elements as are in the rangestd::string *data = alloc.allocate(e - b);// initialize and return a pair constructed from data and// the value returned by uninitialized_copyreturn std::make_pair(data, uninitialized_copy(b, e, data));}inlineStrVec::StrVec(const StrVec &s){// call alloc_n_copy to allocate exactly as many elements as in sstd::pair<std::string*, std::string*> newdata =alloc_n_copy(s.begin(), s.end());elements = newdata.first;first_free = cap = newdata.second;}inlinevoid StrVec::free(){ // may not pass deallocate a 0 pointer; if elements is 0, there's no work to doif (elements) { // destroy the old elements in reverse orderfor (std::string *p = first_free; p != elements; /* empty */)alloc.destroy(--p);alloc.deallocate(elements, cap - elements);}}inlineStrVec &StrVec::operator=(const StrVec &rhs){// call alloc_n_copy to allocate exactly as many elements as in rhsstd::pair<std::string*, std::string*> data =alloc_n_copy(rhs.begin(), rhs.end());free();elements = data.first;first_free = cap = data.second;return *this;}inlinevoid StrVec::reallocate(){ // we'll allocate space for twice as many elements as the current size size_t newcapacity = size() ? 2 * size() : 1;// allocate new memorystd::string *newdata = alloc.allocate(newcapacity);// copy the data from the old memory to the newstd::string *dest = newdata; // points to the next free position in the new array std::string *elem = elements; // points to the next element in the old arrayfor (size_t i = 0; i != size(); ++i)alloc.construct(dest++, *elem++);free(); // free the old space once we've moved the elements // update our data structure to point to the new elements elements = newdata; first_free = dest; cap = elements + newcapacity;}inlineStrVec::StrVec(const std::string *b, const std::string *e){// call alloc_n_copy to allocate exactly as many elements as in ilstd::pair<std::string*, std::string*> newdata = alloc_n_copy(b, e);elements = newdata.first;first_free = cap = newdata.second;}#endif
StrVec.cc
#include "StrVec.h"#include <string>#include <utility>// errata fixed in second printing -- // StrVec's allocator should be a static member not an ordinary member// definition for static data memberstd::allocator<std::string> StrVec::alloc; // all other StrVec members are inline and defined inside StrVec.h
inlinevoid StrVec::push_back(const string& s){ chk_n_alloc(); // ensure that there is room for another element // construct a copy of s in the element to which first_free points alloc.construct(first_free++, s);}inlinevoid StrVec::push_back(string&& s){ chk_n_alloc(); alloc.construct(first_free++, std::move(s));}void fun1(){ StrVec vec; string s="my name is cutter_point!"; vec.push_back(s); //调用const string&这个 vec.push_back("China!"); //调用string&&}
class Foo{public: Foo()=default; Foo(const Foo&); //copy构造函数 Foo &operator=(const Foo&) &; //返回一个左值&&表示返回右值// Foo someMem() & const; //错误,const应放第一位 Foo anotherMem() const &; //正确};Foo &Foo::operator=(const Foo &rhs) &{ return *this;}Foo::Foo(const Foo &f){}void fun2(){ Foo &retFoo(); //返回一个引用,是一个左值 Foo retVal(); //返回一个值,右值调用 Foo i, j; //i,j是左值 i=j; //i是左值// retFoo()=j; //OK这个返回的是一个左值// retVal()=j; //错误。retVal是一个右值}
Overloading and Reference Functions
class Foo{public: Foo()=default;// Foo(const Foo&); //copy构造函数// Foo(Foo&&); Foo &operator=(const Foo&) &; //返回一个左值&&表示返回右值// Foo someMem() & const; //错误,const应放第一位 Foo anotherMem() const &; //正确 Foo sorted() &&; //返回右值 Foo sorted() const &; //返回左值private: vector<int> data;};Foo Foo::sorted() &&{ sort(data.begin(), data.end()); return *this;}Foo Foo::sorted() const &{ Foo ret(*this); sort(ret.data.begin(), ret.data.end()); return ret;}
int main(){ string s1="a value", s2="this is a pig."; auto n=(s1+s2).find('e'); cout<<n<<endl; return 0;}
PS:现在的感觉是很不爽,不知道学这玩意什么时候才能去找工作,不知道去那好,还是耐心点,耐着性子,只要默默地向自己的目标前进就好,未来有我的机遇等着我,我现在要做的就是在机遇来的时候我可以狠狠的抓住!!!以免后悔一生
0 0
- 【足迹C++primer】47、Moving Objects(2)
- 【足迹C++primer】47、Moving Objects(1)
- 【足迹C++primer】表达式求值
- 【足迹C++primer】33、再探迭代器
- 【足迹C++primer】38、关联容器操作(2)
- 【足迹C++primer】15、定义抽象数据类型
- 【足迹C++primer】21、IO类
- 【足迹C++primer】22、文件输入输出
- 【足迹C++primer】23、string流
- 【足迹C++primer】24、顺序容器概述
- 【足迹C++primer】25、容器库概览
- 【足迹C++primer】26、顺序容器操作
- 【足迹C++primer】29、容器适配器
- 【足迹C++primer】32、定制操作_1
- 【足迹C++primer】32、定制操作_2
- 【足迹C++primer】32、定制操作_3
- 【足迹C++primer】35、特定容器算法
- 【足迹C++primer】36、使用关联容器
- Java 内存分配全面浅析
- LeetCode2.2.3 @ Partition List 链表划分 D3F3
- LUA技巧集合
- Why Hadoop2
- 浅谈并发服务器----多线程并发---1
- 【足迹C++primer】47、Moving Objects(2)
- Java常见错误列表
- Win7 C# 控制台程序写注册表被拒,需要以管理员身份运行。
- Codeforces Round #256 (Div. 2) | 前4题
- 2014年开发者需要了解的10大开发趋势和技能
- WinForm中,实现TextBox的验证
- Log4Net使用指南
- Actioncontext和ServletActioncontext的区别
- hdu 3681 Prison Break 扫描线set