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. jQuery制作Web全屏效果

    需要的资源 1.jQuery版本库是必不可少的2.jQuery FullScreen plugin如果你下载不方便的话,你可以直接把下面的代码copy到你本地JQuery FullScreen plu ...

  2. Android之单复选框及Spinner实现二级联动

    一.基础学习 1.图形学真的很神奇啊....查了些资料做出了3D云标签,哈哈...其实直接拿来用的,我们要效仿鲁迅先生的拿来主义,嘿嘿~~3D标签云就是做一个球面,然后再球面上取均匀分布的点,把点坐标 ...

  3. uva 10652 Board Wrapping

    主要是凸包的应用: #include <cstdio> #include <cmath> #include <cstring> #include <algor ...

  4. 在Eclipse中安装ADT

    启动 Eclipse,然后选择 Help > Software Updates….在出现的对话框中,单击 Available Software 选项卡. 单击 Add Site 在 Add Si ...

  5. 自定义滚轮效果选择器spinnerwheel的使用总结

    项目中有使用到像IOS滚轮效果的选择时间或数字的组件:android-spinnerwheel github地址:https://github.com/ai212983/android-spinner ...

  6. 17.1 Replication Configuration 复制配置

    17.1 Replication Configuration 复制配置 17.1.1 How to Set Up Replication 17.1.2 Replication Formats 17.1 ...

  7. 基于SharePoint 的企业信息平台架构

  8. linux下阅读源代码的工具

    说来真是惭愧呀.一直在用VIM 做开发.却不知道VI 里还有这么好使的工具.以前一直都是用: find -type f -print | xargs grep -i **** 在源代码里查找. 原来L ...

  9. (转载)常用JS加密编码算法 五:SHA1算法

    (转载)http://neil-yang.iteye.com/blog/703470 /* * A JavaScript implementation of the Secure Hash Algor ...

  10. EF中使用SQL函数

    SqlFunctions引用命名空间:using System.Data.Objects.SqlClient; db.Favorite.Where(_ => SqlFunctions.PatIn ...