c/c++ 重載運算符 ==和!=的重載

来源:https://www.cnblogs.com/xiaoshiwang/archive/2018/12/19/10146578.html
-Advertisement-
Play Games

重載運算符 ==和!=的重載 問題:假如有一個類似於vector的類,這個類只能存放string,當有2個這個類的對象時,如何比較這2個對象。 自己重載==和!= 代碼(重載==,!=) c++ include include include class string_vector{ friend ...


重載運算符 ==和!=的重載

問題:假如有一個類似於vector的類,這個類只能存放string,當有2個這個類的對象時,如何比較這2個對象。

自己重載==和!=

代碼(重載==,!=)

#include <iostream>
#include <memory>
#include <string>

class string_vector{
  friend bool operator==(const string_vector&, const string_vector&);
  friend bool operator!=(const string_vector&, const string_vector&);
public:
  string_vector():
    elements(nullptr), first_free(nullptr), cap(nullptr){}
  string_vector(const string_vector&);
  string_vector& operator=(const string_vector&);
  string_vector(std::initializer_list<std::string>);
  ~string_vector();
  void push_back(const std::string&);
  
  size_t size() const {
    return first_free - elements;
  };
  
  size_t capacity() const {
    return cap - elements;
  }

  void resize(size_t, std::string&);
  void resize(size_t);

  void reserve(size_t);
  
  std::string* begin() const{return elements;}
  std::string* end() const{return first_free;}
private:
  static std::allocator<std::string> alloc;
  //static const int a = 10;
  void chk_n_alloc(){
    if(size() == capacity())
      reallocate();
  }
  std::pair<std::string*, std::string*> alloc_n_copy
  (const std::string* b, const std::string* e);
  void free();
  void reallocate();
  void reallocate(size_t);
  std::string* elements;//指向第一個元素的指針
  std::string* first_free;//指向最後一個元素的下一個位置的指針
  std::string* cap;//指向vector空間最後一個位置的下一個位置的指針
};

//必須在類的外面再定義一次,否則後面使用alloc的地方,編譯不過
std::allocator<std::string> string_vector::alloc;

std::pair<std::string*, std::string*> string_vector::alloc_n_copy
(const std::string* b, const std::string* e){
  auto data = alloc.allocate(e - b);
  return {data, std::uninitialized_copy(b, e, data)};
}

void string_vector::push_back(const std::string& s){
  chk_n_alloc();
  alloc.construct(first_free++, s);
}

void string_vector::free(){
  if(elements){
    for(auto p = first_free; p != elements;)
      alloc.destroy(--p);
    alloc.deallocate(elements, cap - elements);
  }
}

string_vector::string_vector(const string_vector& s){
  auto newdata = alloc_n_copy(s.begin(), s.end());
  elements = newdata.first;
  first_free = cap = newdata.second;
}
string_vector::string_vector(std::initializer_list<std::string> sl){
  auto newdata = alloc_n_copy(sl.begin(), sl.end());
  elements = newdata.first;
  first_free = cap = newdata.second;
}
string_vector::~string_vector(){
  free();
}

string_vector& string_vector::operator=(const string_vector& rhs){
  auto newdata = alloc_n_copy(rhs.begin(), rhs.end());
  free();
  elements = newdata.first;
  first_free = cap = newdata.second;
  return *this;
}

void string_vector::reallocate(){
  auto newcap = size() ? size() * 2 : 1;
  auto newdata = alloc.allocate(newcap);
  auto dest = newdata;
  auto elem = elements;
  for(size_t i = 0; i != size(); ++i){
    alloc.construct(dest++, std::move(*elem++));
  }
  free();
  elements = newdata;
  first_free = dest;
  cap = elements + newcap;
}

void string_vector::reallocate(size_t sz){
  auto newcap = sz * 2;
  auto newdata = alloc.allocate(newcap);
  auto dest = newdata;
  auto elem = elements;
  for(size_t i = 0; i != size(); ++i){
    alloc.construct(dest++, std::move(*elem++));
  }
  free();
  elements = newdata;
  first_free = dest;
  cap = elements + newcap;
}
void string_vector::reserve(size_t sz){
  if(sz > capacity()){
    reallocate(sz);
  }
}

void string_vector::resize(size_t sz){
  size_t cap = capacity();
  if(sz > cap){
    reallocate(sz);
    for(size_t i = size();i != sz; ++i){
      //調用string的預設構造方法
      alloc.construct(first_free++);
    }
  }
  else if(sz < size()){
    for(size_t i = sz;i != size(); ++i){
      //調用string的西溝函數
      alloc.destroy(--first_free);
    }
  }
}

void string_vector::resize(size_t sz, std::string& s){
  size_t cap = capacity();
  if(sz > cap){
    reallocate(sz);
    for(size_t i = size();i != sz; ++i){
      //調用string的非預設構造方法
      alloc.construct(first_free++, s);
    }
  }
  else if(sz < size()){
    for(size_t i = sz;i != size(); ++i){
      //調用string的西溝函數
      alloc.destroy(--first_free);
    }
  }
}

bool operator==(const string_vector& lhs, const string_vector& rhs){
  if(lhs.size() == rhs.size()){
    auto *p1 = lhs.elements;
    auto *p2 = rhs.elements;
    while(p1 != lhs.first_free){
      if(*p1++ != *p2++){
    return false;
      }
    }
    return true;
  }else{
    return false;
  }
}
bool operator!=(const string_vector& lhs, const string_vector& rhs){
  return !operator==(lhs, rhs);
}
int main(){
  string_vector sv1{"112"};
  string_vector sv2{"11"};
  if(sv1 != sv2){
    std::cout << "!=" << std::endl;
  }
  else{
    std::cout << "==" << std::endl;
  }
}

github

c/c++ 學習互助QQ群:877684253

本人微信:xiaoshitou5854


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 備忘錄模式 Memento 又稱為快照模式 標記Token模式 是一種行為型設計模式,備忘錄模式在外部對對象的狀態進行保存,核心是如何外部保存並且數據還能夠保障安全隱私,本文對備忘錄模式的意圖、結構給出了簡單的介紹,並且給出了代碼的演化過程,以及備忘錄模式的Java實現以及變型,以及備忘錄模式的使用... ...
  • 亂碼的解決 通過過濾器解決亂碼問題:CharacterEncodingFilter 配置web.xml文件 運行結果: 這種方法主要解決的是表單post方法提交的數據,如果是get方法提交的數據,可以: a) 修改tamcat配置 b) 自定義亂碼過濾器 restful風格,優點:輕量級,安全,效率 ...
  • Yii使用單例的場景非常多,比如請求開始創建的Application,Yii,Request,Response等對象功能都十分豐富且開銷也很大,維持一個單例就可供請求的整個生命周期使用。在請求開始即創建,請求結束自行銷毀,中間不銷毀也不創建。這些對象使用了單例沒有疑問,但是這些單例的產生、管理和使用... ...
  • 學習一個設計模式,至少應該明白,這種設計模式要解決什麼問題,什麼時候可以使用,他是如何解決問題的,要記住關鍵代碼,還有優缺點是什麼。 創建型模式 創建型模式顧名思義,就是用來創建對象的。有時候為了保證創建的對象唯一,或者創建的高效等等,就需要用到這些設計模式。 單例模式 單例模式就是保證創建的對象是 ...
  • 如果這是第二次看到我的文章,歡迎右側掃碼訂閱我喲~ 👉 本文長度為4069字,建議閱讀11分鐘。 也許你對降級已經有了一些認識,認真看完,我想這篇文章可能會給你帶來一些新的收穫~ 前面兩篇我們已經聊過了「熔斷」(如何在到處是“雷”的系統中「明哲保身」?這是第一招)和「限流」(想通關「限流」?只要這 ...
  • 啰嗦兩句 前幾天的教程內容量都比較大,今天寫一個相對簡單的,爬取的還是蜂鳥,依舊採用 希望你喜歡 爬取頁面 本篇教程還是基於 學習 的目的,為啥選擇蜂鳥,沒辦法,我瞎選的。 一頓熟悉的操作之後,我找到了下麵的鏈接 這個鏈接返回的是JSON格式的數據 1. page =2頁碼,那麼從1開始進行迴圈就好 ...
  • 一、什麼是字典 字典是python里的一種數據類型,特點是元素的無序性,和鍵key的唯一性。字典的創建方法是{key:values},字典里的鍵key只能是不可變的數據類型(整型,字元串或者是元組),值values可以是任何數據類型。字典里的一組key:values叫做一個鍵值對item。 二、字典 ...
  • 函數: 將特定功能代碼編寫在一個函數里 便於閱讀和復用 對一組表達特定功能表達式的封裝 使程式模塊化 python內置函數: input(),print(),eval()... 函數定義 函數語法格式: def <函數名>(<參數列表>): <函數體> return <返回值列表> 函數調用過程: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...