习题13-41
前置运算返回的是先加一,再返回值;后置运算是先返回值,再加一。
这里,由于是尾后指针,后置运算比较合理;如果用前置运算,就不会给first_free的初始尾后指针位置赋值,并且将最后的尾后指针cap赋值了;
习题13-42
替换一下即可;
习题13-43
for_each(elements,first_free,[](string &s){alloc.destory(&s)});
习题13-44
程序编写完成之后,编译的时候出错,但找不到问题所在。
参考:https://blog.csdn.net/XHM11450/article/details/83994448即可解决。
class String
{
public:
String() :elements(nullptr), first_free(nullptr) {}
String(const String &);
String(const char *);
String &operator=(const String&);
~String();
size_t size()const { return first_free - elements; }
char *begin() const { return elements; }
char *end() const { return first_free; }
private:
allocator<char> alloc;
pair<char *, char *> alloc_n_copy(const char *, const char *);
void free();
char *elements;
char *first_free;
};
pair<char *, char *> String::alloc_n_copy(const char *b, const char *e)
{
auto data = alloc.allocate(e - b);
return {data, uninitialized_copy(b, e, data)};
}
void String::free()
{
if (elements)
{
for (auto p = first_free; p != elements; )
alloc.destroy(--p);
alloc.deallocate(elements, first_free - elements);
}
}
String::String(const String &s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
cout << "you ";
elements = newdata.first;
first_free = newdata.second;
}
String::String(const char *a)
{
char *b = const_cast<char*> (a);
while (*b)
{
++b;
}
auto newdata = alloc_n_copy(a, b);
elements = newdata.first;
first_free = newdata.second;
}
String::~String()
{
free();
}
String &String::operator=(const String &rhs)
{
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = data.second;
return *this;
}
习题13-45
左值引用:常规引用;
右值引用:绑定到右值的引用;
习题13-46
1.右值引用;函数返回值是一个右值;
2.左值引用;下标返回值是一个左值;
3.左值引用,变量是左值;
4.右值引用。算术表达式返回右值;
习题13-47
class String
{
public:
String() :elements(nullptr), first_free(nullptr) {}
String(const String &);
String(const char *);
String &operator=(const String&);
~String();
size_t size()const { return first_free - elements; }
char *begin() const { return elements; }
char *end() const { return first_free; }
private:
allocator<char> alloc;
pair<char *, char *> alloc_n_copy(const char *, const char *);
void free();
char *elements;
char *first_free;
};
pair<char *, char *> String::alloc_n_copy(const char *b, const char *e)
{
auto data = alloc.allocate(e - b);
return {data, uninitialized_copy(b, e, data)};
}
void String::free()
{
if (elements)
{
for (auto p = first_free; p != elements; )
alloc.destroy(--p);
alloc.deallocate(elements, first_free - elements);
}
}
String::String(const String &s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
cout << "拷贝构造 "<<endl;
elements = newdata.first;
first_free = newdata.second;
}
String::String(const char *a)
{
char *b = const_cast<char*> (a);
cout << "构造 "<<endl;
while (*b)
{
++b;
}
auto newdata = alloc_n_copy(a, b);
elements = newdata.first;
first_free = newdata.second;
}
String::~String()
{
free();
}
String &String::operator=(const String &rhs)
{
cout << "拷贝赋值 "<<endl;
auto data = alloc_n_copy(rhs.begin(), rhs.end());
free();
elements = data.first;
first_free = data.second;
return *this;
}
void main()
{
String s1("Syou");
String s2 = s1;
String s3(s1);
}
习题13-48
String s1("Syou");
String s2 = s1;
String s3(s1);
vector<String> vec;
vec.push_back(s1);
vec.push_back(s2);
vec.push_back(s3);
习题13-49
Message的移动构造函数和移动赋值运算符照着书写就行;
StrVec::StrVec(StrVec &&s)noexcept:elements(s.elements), first_free(s.first_free), cap(s.cap)
{
s.elements = s.first_free = s.cap = nullptr;
}
StrVec &StrVec::operator=(StrVec &&rhs)noexcept
{
if (this != &rhs)
{
free();
elements = rhs.elements;
first_free = rhs.first_free;
cap = rhs.cap;
rhs.elements = rhs.first_free = rhs.cap = nullptr;
}
return *this;
}
String::String(String&& s) noexcept: elements(s.elements), first_free(s.first_free)
{
s.elements = s.first_free= nullptr;
}
String& String::operator=(String&& rhs) noexcept
{
if (this != &rhs) {
free();
elements = rhs.elements;
first_free= rhs.first_free;
rhs.elements = rhs.first_free= nullptr;
}
return *this;
}
习题13-50
String::String(String&& s) noexcept: elements(s.elements), first_free(s.first_free)
{
cout << "移动构造" << endl;
s.elements = s.first_free= nullptr;
}
String& String::operator=(String&& rhs) noexcept
{
cout << "移动赋值"<<endl;
if (this != &rhs) {
free();
elements = rhs.elements;
first_free= rhs.first_free;
rhs.elements = rhs.first_free= nullptr;
}
return *this;
}
void main()
{
String s1("Syou");
String s2 = s1;
String s3(s1);
vector<String> vec;
vec.push_back(s1);
vec.push_back(s2);
vec.push_back(s3);
}
构造 //第一行
拷贝构造 //第二行
拷贝构造 //第三行
拷贝构造 // 第五行,vec为空,创建分配一个空间,拷贝s1
移动构造 //移动s1,第六行,vec的空间由1变为2,移动s1
拷贝构造 //拷贝s2,第六行
移动构造 // 移动s1,第七行 vec的空间由2变为4,移动s1、s2
移动构造 // 移动s2, 第七行
拷贝构造 //拷贝s3,第七行