自定義簡易string類c++primer13.44
標頭檔案
#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;
}
相關文章
- iOS自定義控制元件:簡易下拉控制元件iOS控制元件
- springcloud之自定義簡易消費服務元件SpringGCCloud元件
- 自定義異常類
- 掌握 ASP.NET 之路:自定義實體類簡介ASP.NET
- 直播系統原始碼,簡易的自定義確認彈框AlertDialog原始碼
- 易優cms模板在哪自定義表單
- 短視訊程式開發,簡易的自定義確認彈框AlertDialog
- Django(62)自定義認證類Django
- 自定義實現Complex類
- Java的自定義異常類Java
- 工具類——自定義Collections集合方法
- Laravel自定義Make命令生成Service類Laravel
- Java自定義一個字典類(Dictionary)Java
- 自定義一個類載入器
- C#中自定義異常類C#
- SwiftUI 簡明教程之自定義 ModifierSwiftUI
- ios自定義簡約導航欄iOS
- jQuery自定義事件簡單介紹jQuery事件
- 自定義簡單的RatingBar
- 自定義簡單彈幕實現
- 一個簡單的自定義Collection
- android簡單的自定義動畫Android動畫
- 【JAVA】自定義類載入器實現類隔離Java
- PHP 自定義session儲存 FILE 方式類PHPSession
- 前端自定義類事件回撥封裝前端事件封裝
- C++:使自定義類支援迭代器C++
- 簡單的string類的模擬實現
- 自定義類載入器驗證類載入機制
- JVM系列之類載入流程-自定義類載入器JVM
- 自定義jquery外掛簡單介紹jQuery
- jQuery自定義外掛簡單介紹jQuery
- 使用 Laravel Resource 類時自定義分頁資訊Laravel
- 類似if一樣的自定義程式碼塊
- 【譯】如何自定義Flask中的響應類Flask
- 自定義ALV欄位分類時注意
- JAVA集合類簡要筆記 - 內部類 包裝類 Object類 String類 BigDecimal類 system類Java筆記ObjectDecimal
- 類載入流程,類載入機制及自定義類載入器
- 自定義View:自定義屬性(自定義按鈕實現)View