【足迹C++primer】47、Moving Objects(2)
版权声明:本文为博主原创文章。未经博主同意不得转载。 https://blog.csdn.net/cutter_point/article/details/37954805
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 class
class StrVec {
public:
	// copy control members
    StrVec():
	  elements(0), first_free(0), cap(0) { }
	StrVec(const StrVec&);            // copy constructor
	StrVec &operator=(const StrVec&); // copy assignment
	~StrVec();                            // destructor
	// additional constructor
	StrVec(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 interface
	std::string *begin() const { return elements; }
	std::string *end() const { return first_free; }
	// operator functions covered in chapter 14
	std::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 StrVec
	void chk_n_alloc()
		{ if (size() == capacity()) reallocate(); }
    // used by the copy constructor, assignment operator, and destructor
	std::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>
inline
StrVec::~StrVec() { free(); }
inline
std::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 range
	std::string *data = alloc.allocate(e - b);
	// initialize and return a pair constructed from data and
	// the value returned by uninitialized_copy
	return std::make_pair(data, uninitialized_copy(b, e, data));
}
inline
StrVec::StrVec(const StrVec &s)
{
	// call alloc_n_copy to allocate exactly as many elements as in s
	std::pair<std::string*, std::string*> newdata =
							alloc_n_copy(s.begin(), s.end());
	elements = newdata.first;
	first_free = cap = newdata.second;
}
inline
void StrVec::free()
{
    // may not pass deallocate a 0 pointer; if elements is 0, there's no work to do
	if (elements) {
    	// destroy the old elements in reverse order
		for (std::string *p = first_free; p != elements; /* empty */)
			alloc.destroy(--p);
		alloc.deallocate(elements, cap - elements);
	}
}
inline
StrVec &StrVec::operator=(const StrVec &rhs)
{
	// call alloc_n_copy to allocate exactly as many elements as in rhs
	std::pair<std::string*, std::string*> data =
							alloc_n_copy(rhs.begin(), rhs.end());
	free();
	elements = data.first;
	first_free = cap = data.second;
	return *this;
}
inline
void StrVec::reallocate()
{
    // we'll allocate space for twice as many elements as the current size
    size_t newcapacity = size() ? 2 * size() : 1;
	// allocate new memory
	std::string *newdata = alloc.allocate(newcapacity);
	// copy the data from the old memory to the new
	std::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 array
	for (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;
}
inline
StrVec::StrVec(const std::string *b, const std::string *e)
{
	// call alloc_n_copy to allocate exactly as many elements as in il
	std::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 member
std::allocator<std::string> StrVec::alloc;  
// all other StrVec members are inline and defined inside StrVec.h
inline
void 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);
}
inline
void 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:如今的感觉是非常不爽。不知道学这玩意什么时候才干去找工作。不知道去那好,还是耐心点。耐着性子,仅仅要默默地向自己的目标前进就好。未来有我的机遇等着我,我如今要做的就是在机遇来的时候我能够狠狠的抓住!
!!
以免懊悔一生
【足迹C++primer】47、Moving Objects(2)的更多相关文章
- 【足迹C++primer】47、Moving Objects(1)
		
Moving Objects(1) * 功能:Moving Objects * 时间:2014年7月17日08:46:45 * 作者:cutter_point */ #include<iostr ...
 - 【足迹C++primer】46、动态存储类
		
动态存储类 StrVec Class Design StrVec Class Definition class StrVec { public: //构造函数 StrVec():elements(nu ...
 - 【足迹C++primer】52、,转换和继承虚函数
		
转换和继承,虚函数 Understanding conversions between base and derived classes is essential to understanding h ...
 - 【足迹C++primer】48、函数引用操作符
		
函数引用操作符 struct absInt { int operator()(int val) const { cout<<val<<"<->!!!&qu ...
 - [paper]MaskFusion: Real-Time Recognition, Tracking and Reconstruction of Multiple Moving Objects
		
Before 近期在调研关于RGBD在室内移动机器人下的语义导航的研究.目前帝国理工的Andrew Davison在这边有两个团队在研究,分别是Fusion++ 和 这篇 MaskFusion.这篇是 ...
 - 【足迹C++primer】表达式求值
		
表达式求值 /** * 功能:表达式求值(0到9) * 时间:2014年6月15日08:02:31 * 作者:cutter_point */ #include<stdlib.h> #inc ...
 - 【足迹C++primer】30、概要(泛型算法)
		
概要(泛型算法) 大多数算法的头文件中定义algorithm在. 标准库也是第一个文件numeric它定义了一套通用算法. #include<iostream> #include<n ...
 - 【足迹C++primer】40、动态数组
		
动态数组 C++语言定义了第二种new表达式语法.能够分配并初始化一个对象数组.标准库中包括 一个名为allocator的类.同意我们将分配和初始化分离. 12.2.1 new和数组 void fun ...
 - 【足迹C++primer】49、超载,变化,运营商
		
超载,变化,运营商 Conversion Operators 转换操作符 operator type() const Conversions to an array or a function typ ...
 
随机推荐
- 【Mock.js】前端模拟假数据,不用在手拼了
			
[Mock.js]前端模拟假数据,不用在手拼了:https://www.jianshu.com/p/8579b703a4c1
 - How To Release and/or Renew IP Addresses on Windows XP | 2000 | NT
			
Type 'ipconfig' (without the quotes) to view the status of the computer's IP address(es). If the com ...
 - python时间日期处理
			
一.模块介绍: 1.time模块接近操作系统,模块中的大多数函数是调用了所在平台C library的同名函数,部分函数式平台相关的:基于Unix Timestamp,能表述的日期范围被限定在 1970 ...
 - http请求访问响应慢问题解决的基本思路
			
第一步,检查网络 ping命令检查网络域名解析是否正常,ping服务器的延迟是否过大,如果过大可以检查Ip是否冲突,或者交换机网线是否正常插好,通过nmon还可以查看网络流量,一般用的千兆交换机理论速 ...
 - nodejs包高效升级插件npm-check-updates
			
一.安装 npm install -g npm-check-updates 或 cnpm install -g npm-check-updates 二.使用 ncu crypto ^0.0.3 → ^ ...
 - linux-java
			
查看Java进程耗内存线程 top -Hp pid printf '%x\n' pid ->jid(java thread) 查看time值最大 jstack pid | grep jid 查看 ...
 - HWDB手写汉字识别 - CNN
			
MARK Caffe 的 googleNet近似模型,识别HWDB汉字200类 准确率96.3
 - oracle 数据库插入中文乱码
			
一. 查询数据库编码 select userenv('language') from dual; 查询服务器编码 select * from v$nls_parameters; 推出sql查询系统编码 ...
 - get和post 两种基本请求方式的区别
			
GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...
 - Struts拦截器Interceptor
			
Struts2 拦截器 [Interceptor] 拦截器的工作原理如上图,每一个Action请求都包装在一系列的拦截器的内部.拦截器可以在Action执行直线做相似的操作也可以在Action执行直后 ...