13.50 没有定义析构函数

#include<iostream>
#include<string>
#include<memory>
#include<utility>
#include<cstring>
#include<vector>
using namespace std; class String
{
public:
String():elements(nullptr),first_free(nullptr) {}
String(char *c);
String(const String&);
String& operator=(const String&);
string* begin() const { return elements;}
string* end() const { return first_free;} String(String &&);
String& operator=(String &&);
private:
static allocator<string> alloc;
string *elements;
string *first_free;
}; allocator<string> String::alloc;
String::String(char *c)
{
size_t capacity=strlen(c);
auto data=alloc.allocate(capacity);
auto dest=data;
string s;
s.copy(c,strlen(c));
alloc.construct(dest++,s);
elements=data;
first_free=dest;
} String::String(const String &s)
{
cout<<"copy construct"<<endl;
auto capacity=s.end()-s.begin();
auto data=alloc.allocate(capacity);
uninitialized_copy(s.begin(),s.end(),data);
elements=data;
first_free=data+capacity;
} String& String::operator=(const String &s)
{
cout<<"copy = construct"<<endl;
auto capacity=s.end()-s.begin();
auto data=alloc.allocate(capacity);
uninitialized_copy(s.begin(),s.end(),data);
if(elements)
{
auto begin=elements;
auto end=first_free;
while(begin!=end)
alloc.destroy(begin++);
alloc.deallocate(elements,first_free-elements);
}
elements=data;
first_free=data+capacity;
return *this;
} String::String(String &&s):elements(s.elements),first_free(s.first_free)
{
cout<<"move construct"<<endl;
s.elements=s.first_free=nullptr;
} String& String::operator=(String &&s)
{
cout<<"move = construct"<<endl;
if(this!=&s)
{
if(elements)
{
auto begin=elements;
auto end=first_free;
while(begin!=end)
alloc.destroy(begin++);
alloc.deallocate(elements,first_free-elements);
}
}
elements=s.elements;
first_free=s.first_free;
s.elements=s.first_free=nullptr;
return *this;
} int main()
{
vector<String> vec;
char ch[]="hello";
char ch1[]="world!";
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
return ;
}

运行结果如下:  结果中出现移动构造函数是因为调用String构造函数返回的结果是右值

定义析构函数时:

#include<iostream>
#include<string>
#include<memory>
#include<utility>
#include<cstring>
#include<vector>
using namespace std; class String
{
public:
String():elements(nullptr),first_free(nullptr){}
String(char *c);
String(const String&);
String& operator=(const String&);
string* begin() const { return elements;}
string* end() const { return first_free;}
//一定要定义析构函数,否则就算定义了移动构造函数还是不会调用,只会调用拷贝构造函数
~String()
{
if(elements)
{
auto begin=elements;
auto end=first_free;
while(begin!=end)
alloc.destroy(begin++);
alloc.deallocate(elements,first_free-elements);
}
}
String(String &&) noexcept;
String& operator=(String &&) noexcept;
private:
static allocator<string> alloc;
string *elements;
string *first_free;
}; allocator<string> String::alloc;
String::String(char *c)
{
size_t capacity=strlen(c);
auto data=alloc.allocate(capacity);
auto dest=data;
string s;
s.copy(c,strlen(c));
alloc.construct(dest++,s);
elements=data;
first_free=dest;
} String::String(const String &s)
{
cout<<"copy construct"<<endl;
auto capacity=s.end()-s.begin();
auto data=alloc.allocate(capacity);
uninitialized_copy(s.begin(),s.end(),data);
elements=data;
first_free=data+capacity;
} String& String::operator=(const String &s)
{
cout<<"copy = construct"<<endl;
auto capacity=s.end()-s.begin();
auto data=alloc.allocate(capacity);
uninitialized_copy(s.begin(),s.end(),data);
if(elements)
{
auto begin=elements;
auto end=first_free;
while(begin!=end)
alloc.destroy(begin++);
alloc.deallocate(elements,first_free-elements);
}
elements=data;
first_free=data+capacity;
return *this;
} String::String(String &&s) noexcept :elements(s.elements),first_free(s.first_free)
{
cout<<"move construct"<<endl;
s.elements=s.first_free=nullptr;
} String& String::operator=(String &&s) noexcept
{
cout<<"move = construct"<<endl;
if(this!=&s)
{
if(elements)
{
auto begin=elements;
auto end=first_free;
while(begin!=end)
alloc.destroy(begin++);
alloc.deallocate(elements,first_free-elements);
}
}
elements=s.elements;
first_free=s.first_free;
s.elements=s.first_free=nullptr;
return *this;
} int main()
{
vector<String> vec;
char ch[]="hello";
char ch1[]="world!";
cout<<vec.capacity()<<endl;
cout<<endl;
String ss(ch);
vec.push_back(ss);
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<endl;
vec.push_back(String(ch1));
cout<<vec.capacity()<<endl;
cout<<"\n"; std::vector<String> v;
String s;
for (unsigned i = ; i != ; ++i)
{
std::cout << v.capacity() << "\n";
v.push_back(s);
}
return ;
}

运行结果如下:

在String中添加移动构造函数和移动赋值运算符的更多相关文章

  1. [JS]给String对象添加方法,使传入的字符串字符之间以空格分开输出

    看到一个这样子的面试题: 给String对象添加一个方法,传入一个string类型的参数,然后将string的每一个字符间加空格返回,例如:addSpace("hello world&quo ...

  2. 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接

    长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...

  3. C++中 类的构造函数理解(一)

    C++中 类的构造函数理解(一) 写在前面 这段时间完成三个方面的事情: 1.继续巩固基础知识(主要是C++ 方面的知识) 2.尝试实现一个iOS的app,通过完成app,学习iOS开发中要用到的知识 ...

  4. 在RichTextBox控件中添加图片和文字

    public void SetText(RichTextBox rtb) { rtb.Text = "在RichTextBox控件中添加图片和文字" + Environment.N ...

  5. 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】

    Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...

  6. 编写高质量代码改善C#程序的157个建议——建议106:为静态类添加静态构造函数

    建议106:为静态类添加静态构造函数 静态类可以拥有构造方法,这就是静态构造方法.静态构造方法与实例构造方法比较有几个自己的特点: 只被执行一次,且在第一次调用类成员之前被运行时执行. 代码无法调用它 ...

  7. Vue.set 向响应式对象中添加响应式属性,及设置数组元素触发视图更新

    一.为什么需要使用Vue.set? vue中不能检测到数组和对象的两种变化: 1.数组长度的变化 vm.arr.length = 4 2.数组通过索引值修改内容 vm.arr[1] = ‘aa’ Vu ...

  8. spring中bean的构造函数,Autowired(Value)注入与@PostConstruct调用顺序

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/yyysylvia/article/deta ...

  9. 用Retrofit发送请求中添加身份验证

    用Retrofit发送请求中添加身份验证====================在安卓应用开发中, retrofit可以极大的方便发送http网络请求,不管是GET, POST, 还是PUT, DEL ...

随机推荐

  1. PHP错误Warning: Cannot modify header information - headers already sent by解决方法

    这篇文章主要介绍了PHP错误Warning: Cannot modify header information - headers already sent by解决方法,需要的朋友可以参考下 今天在 ...

  2. sharepoint 2013 安装配置PowerView

    安装sharepoint 2013 网络上有很多说明.这里列出两个实例: 1.说得比较详细,并提供了下载连接:http://www.sqlant.com/2012/10/sharepoint-2013 ...

  3. maven 根据不同的环境打war包-->资源文件的处理方式

    发现犯的错误: 1. 指定了testResource 文件夹与resource 为同一个文件夹.导致不论在resource 里面如何过滤文件,都不起作用.资源文件本来就是共享的.不必这样指定. 2. ...

  4. Rotate

    hdu4998:http://acm.hdu.edu.cn/showproblem.php?pid=4998 题意:给你n个点,以及绕每个点旋转的弧度.然后,问你经过这n次旋转,平面中的点总的效果是相 ...

  5. Sql中的datetime类型的空值和c#中的DateTime的空值的转换方法

    [一篮饭特稀原创,转载请注明出自http://www.cnblogs.com/wanghafan/p/3412796.html] 在NET 2.0以上版本提供了一种新的方法 就是加问号,DateTim ...

  6. [OJ] Search for a Range

    LintCode 61. Search for a Range (Medium) LeetCode 34. Search for a Range (Medium) class Solution { p ...

  7. Perl脚本学习经验(四)--Perl中sftp的使用

    使用sftp,需要使用Except模块,该模块需要下载安装在perl目录下,可以上http://www.cpan.org/上下载对应的安装包:1. 用root用户登录环境:2. cd /usr/lib ...

  8. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: SELECT command denied to user’

    Linux环境 Mysql+Hibernate command denied to user 错误 错误信息 如下: com.mysql.jdbc.exceptions.jdbc4.MySQLSynt ...

  9. bzoj2333

    好题,先离线把连通块变成连续的区间每次连通块合并就相当于两个区间合并这样就轻易的用线段树解决了 type node=record wh:string[]; x,y:longint; end; ..*] ...

  10. SQL重复记录处理(查找,过滤,删除)

    SQL重复记录处理(查找,过滤,删除)     ID int    Title nvarchar(50)    AddDate datetime    数据  www.2cto.com     ID ...