头文件
#pragma warning(disable:4996) //可参考上一篇解决c4996问题的博客
#include<iostream>
#include<memory>
#include<algorithm>
#include<utility>
class String {
public:
String() {
elements = nullptr;
first_free = nullptr;
}
String(char *c) { //接受c风格的字符串,c指向字符串第一个字符
auto c1 = const_cast<char *>(c);
while (*c1) {
++c1;
}
auto p = alloc_n_copy(c, c1);
elements = p.first;
first_free = p.second;
}
String(const String& s) {
auto p = alloc_n_copy(s.elements, s.first_free);
elements = p.first;
first_free = p.second;
}
String &operator=(const String& s) {
auto p = alloc_n_copy(s.elements, s.first_free);
free();
elements = p.first;
first_free = p.second;
}
~String() {
free();
}
void show() {
auto p = elements;
while (p != first_free) {
std::cout << *p;
++p;
}
std::cout << std::endl;
}
size_t size() { return first_free - elements; }
String &operator+(String& s) {
auto p = alloc.allocate(this->size() + s.size());
//注释部分为拷贝实现
/*auto dataMid = std::uninitialized_copy(this->elements, this->first_free, p);
auto dataEnd = std::uninitialized_copy(s.elements, s.first_free, dataMid);
this->free();
this->elements = p;
this->first_free = dataEnd;*/
//下面采用了移动构造函数std::move,节省了拷贝开销
auto dest = p; //指向新数组中下一个空闲位置
auto elem = this->elements; //指向就数组中下一个元素
for (size_t i = 0; i != this->size(); ++i) {
alloc.construct(dest++, std::move(*elem++));
}
elem = s.elements;
for (size_t i = 0; i != s.size(); ++i) {
alloc.construct(dest++, std::move(*elem++));
}
free();
this->elements = p;
this->first_free = dest;
return *this;
}
private:
char *elements; //指向字符串首字符
char *first_free; //指向字符串最后一个字符的后一个位置
static std::allocator<char> alloc; //类内静态成员要在类外进行定义初始化否则会出现LNK2001error
static std::allocator<char> initalloc() {
std::allocator<char> allo;
allo.allocate(1);
return allo;
}
std::pair<char*, char*> alloc_n_copy(const char*, const char*);
void free();
};
std::allocator<char> String::alloc = initalloc();
std::pair<char*, char*> String::alloc_n_copy(const char* c1, const char* c2) {
auto dataBeg = alloc.allocate(c2 - c1);
auto dataEnd = std::uninitialized_copy(c1, c2, dataBeg);
return std::make_pair(dataBeg, dataEnd);
}
void String::free() {
if (elements) {
std::for_each(elements, first_free, [this](char &rhs) {alloc.destroy(&rhs); });
alloc.deallocate(elements, first_free - elements);
}
}
主函数
#include<iostream>
#include"classString.h"
using namespace std;
int main() {
String s("dasdsad11111");
s.show();
String s1(s);
s1.show();
String s2 = s;
s2.show();
cout << s2.size() << endl;
s1 + s2;
s1.show();
return 0;
}