重载运算符 ==和!=的重载

问题:假如有一个类似于vector的类,这个类只能存放string,当有2个这个类的对象时,如何比较这2个对象。

自己重载==和!=

代码(重载==,!=)

  1. #include <iostream>
  2. #include <memory>
  3. #include <string>
  4. class string_vector{
  5. friend bool operator==(const string_vector&, const string_vector&);
  6. friend bool operator!=(const string_vector&, const string_vector&);
  7. public:
  8. string_vector():
  9. elements(nullptr), first_free(nullptr), cap(nullptr){}
  10. string_vector(const string_vector&);
  11. string_vector& operator=(const string_vector&);
  12. string_vector(std::initializer_list<std::string>);
  13. ~string_vector();
  14. void push_back(const std::string&);
  15. size_t size() const {
  16. return first_free - elements;
  17. };
  18. size_t capacity() const {
  19. return cap - elements;
  20. }
  21. void resize(size_t, std::string&);
  22. void resize(size_t);
  23. void reserve(size_t);
  24. std::string* begin() const{return elements;}
  25. std::string* end() const{return first_free;}
  26. private:
  27. static std::allocator<std::string> alloc;
  28. //static const int a = 10;
  29. void chk_n_alloc(){
  30. if(size() == capacity())
  31. reallocate();
  32. }
  33. std::pair<std::string*, std::string*> alloc_n_copy
  34. (const std::string* b, const std::string* e);
  35. void free();
  36. void reallocate();
  37. void reallocate(size_t);
  38. std::string* elements;//指向第一个元素的指针
  39. std::string* first_free;//指向最后一个元素的下一个位置的指针
  40. std::string* cap;//指向vector空间最后一个位置的下一个位置的指针
  41. };
  42. //必须在类的外面再定义一次,否则后面使用alloc的地方,编译不过
  43. std::allocator<std::string> string_vector::alloc;
  44. std::pair<std::string*, std::string*> string_vector::alloc_n_copy
  45. (const std::string* b, const std::string* e){
  46. auto data = alloc.allocate(e - b);
  47. return {data, std::uninitialized_copy(b, e, data)};
  48. }
  49. void string_vector::push_back(const std::string& s){
  50. chk_n_alloc();
  51. alloc.construct(first_free++, s);
  52. }
  53. void string_vector::free(){
  54. if(elements){
  55. for(auto p = first_free; p != elements;)
  56. alloc.destroy(--p);
  57. alloc.deallocate(elements, cap - elements);
  58. }
  59. }
  60. string_vector::string_vector(const string_vector& s){
  61. auto newdata = alloc_n_copy(s.begin(), s.end());
  62. elements = newdata.first;
  63. first_free = cap = newdata.second;
  64. }
  65. string_vector::string_vector(std::initializer_list<std::string> sl){
  66. auto newdata = alloc_n_copy(sl.begin(), sl.end());
  67. elements = newdata.first;
  68. first_free = cap = newdata.second;
  69. }
  70. string_vector::~string_vector(){
  71. free();
  72. }
  73. string_vector& string_vector::operator=(const string_vector& rhs){
  74. auto newdata = alloc_n_copy(rhs.begin(), rhs.end());
  75. free();
  76. elements = newdata.first;
  77. first_free = cap = newdata.second;
  78. return *this;
  79. }
  80. void string_vector::reallocate(){
  81. auto newcap = size() ? size() * 2 : 1;
  82. auto newdata = alloc.allocate(newcap);
  83. auto dest = newdata;
  84. auto elem = elements;
  85. for(size_t i = 0; i != size(); ++i){
  86. alloc.construct(dest++, std::move(*elem++));
  87. }
  88. free();
  89. elements = newdata;
  90. first_free = dest;
  91. cap = elements + newcap;
  92. }
  93. void string_vector::reallocate(size_t sz){
  94. auto newcap = sz * 2;
  95. auto newdata = alloc.allocate(newcap);
  96. auto dest = newdata;
  97. auto elem = elements;
  98. for(size_t i = 0; i != size(); ++i){
  99. alloc.construct(dest++, std::move(*elem++));
  100. }
  101. free();
  102. elements = newdata;
  103. first_free = dest;
  104. cap = elements + newcap;
  105. }
  106. void string_vector::reserve(size_t sz){
  107. if(sz > capacity()){
  108. reallocate(sz);
  109. }
  110. }
  111. void string_vector::resize(size_t sz){
  112. size_t cap = capacity();
  113. if(sz > cap){
  114. reallocate(sz);
  115. for(size_t i = size();i != sz; ++i){
  116. //调用string的默认构造方法
  117. alloc.construct(first_free++);
  118. }
  119. }
  120. else if(sz < size()){
  121. for(size_t i = sz;i != size(); ++i){
  122. //调用string的西沟函数
  123. alloc.destroy(--first_free);
  124. }
  125. }
  126. }
  127. void string_vector::resize(size_t sz, std::string& s){
  128. size_t cap = capacity();
  129. if(sz > cap){
  130. reallocate(sz);
  131. for(size_t i = size();i != sz; ++i){
  132. //调用string的非默认构造方法
  133. alloc.construct(first_free++, s);
  134. }
  135. }
  136. else if(sz < size()){
  137. for(size_t i = sz;i != size(); ++i){
  138. //调用string的西沟函数
  139. alloc.destroy(--first_free);
  140. }
  141. }
  142. }
  143. bool operator==(const string_vector& lhs, const string_vector& rhs){
  144. if(lhs.size() == rhs.size()){
  145. auto *p1 = lhs.elements;
  146. auto *p2 = rhs.elements;
  147. while(p1 != lhs.first_free){
  148. if(*p1++ != *p2++){
  149. return false;
  150. }
  151. }
  152. return true;
  153. }else{
  154. return false;
  155. }
  156. }
  157. bool operator!=(const string_vector& lhs, const string_vector& rhs){
  158. return !operator==(lhs, rhs);
  159. }
  160. int main(){
  161. string_vector sv1{"112"};
  162. string_vector sv2{"11"};
  163. if(sv1 != sv2){
  164. std::cout << "!=" << std::endl;
  165. }
  166. else{
  167. std::cout << "==" << std::endl;
  168. }
  169. }

github

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ 重载运算符 ==和!=的重载的更多相关文章

  1. 【STL】重载运算符

    重载运算符 为什么要重载运算符: C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如结构体),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予 ...

  2. 【noi 2.6_9290】&【poj 2680】Computer Transformation(DP+高精度+重载运算符)

    题意:给一个初始值1,每步操作将1替换为01,将0替换为10.问N步操作后有多少对连续的0. 解法:f[i]表示第i步后的答案.可以直接打表发现规律--奇数步后,f[i]=f[i-1]*2-1;偶数步 ...

  3. c++的重载运算符

    c++中允许重载运算符: 这是我辛苦的结果 #include"iostream"using namespace std;class aaa{ int x;public: aaa() ...

  4. C# 重载运算符

    如果你想让自己定义的类型可以用运算符进行运算,那么可以通过重载运算符来实现: 示例: class Salary { public int RMB { get; set; } public static ...

  5. c++中有些重载运算符为什么要返回引用

    事实上,我们的重载运算符返回void.返回对象本身.返回对象引用都是可以的,并不是说一定要返回一个引用,只不过在不同的情况下需要不同的返回值. 那么什么情况下要返回对象的引用呢? 原因有两个: 允许进 ...

  6. C++ Primer : : 第十四章 : 重载运算符与类型转换之类型转换运算符和重载匹配

    类型转换运算符 class SmallInt { public: SmallInt(int i = 0) : val(i) { if (i < 0 || i > 255) throw st ...

  7. C++ Primer : 第十四章 : 重载运算与类型转换之重载运算符

    重载前须知 重载运算符是特殊的函数,它们的名字由operator和其后要重载的运算符号共同组成. 因为重载运算符时函数, 因此它包含返回值.参数列表和函数体. 对于重载运算符是成员函数时, 它的第一个 ...

  8. Swift开发第六篇——操作运算符也可以重载& func 的参数修饰

    本篇分为两部分: 1.Swift 中重载操作运算符的使用 2.Swfit 中 func 的参数修饰 1.Swift 中重载操作运算符的使用 与别的语言不同,Swift 支持运算符的重载,运算符指的是“ ...

  9. C#基础知识系列一(goto、i++、三元运算符、ref和out、String和string、重载运算符)

    前言 这两天在网上看到的总结很多,尤其是博客园中的,很多很多,也给了我很多的启发,当然自己也总结过,而且有很多人也给与我一些意见和看法.不管怎样,自己还是先把所谓的基础知识加强巩固下吧. 2014年的 ...

随机推荐

  1. markdown反射型xss漏洞复现

    markdown xss漏洞复现 转载至橘子师傅:https://blog.orange.tw/2019/03/a-wormable-xss-on-hackmd.html 漏洞成因 最初是看到Hack ...

  2. 如何为自己的pip包打造可以执行的系统命令

    1.我们在打包我们自己的Python Package的时候.我们不仅可以在代码中使用我们的package,而且可以添加一些可执行命令来执行自己的函数. 2 .我们应该怎么办呢? 1.首先新建目录以及文 ...

  3. 【视频】使用ASP.NET Core开发GraphQL服务

    GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL来自Facebook,它于2012年开始开发,2015年开源. GraphQL与编程语言无关,可以使用很 ...

  4. Python爬虫入门教程 16-100 500px摄影师社区抓取摄影师数据

    写在前面 今天要抓取的网站为 https://500px.me/ ,这是一个摄影社区,在一个摄影社区里面本来应该爬取的是图片信息,可是我发现好像也没啥有意思的,忽然觉得爬取一下这个网站的摄影师更好玩一 ...

  5. 输入法设置,SublimeTest,putty掉线

    设置默认中文 在我们使用计算机中,如果输入法的默认语言是英文,那么我们操作起来会更加方便,那我们怎么设置呢??? 以Windows10为例 SublimeTest相关设置 SublimeTest出现乱 ...

  6. 消息队列中间件(二)使用 ActiveMQ

    ActiveMQ 介绍 Active MQ 是由 Apache 出品的一款流行的功能强大的开源消息中间件,它速度快,支持跨语言的客户端,具有易于使用的企业集成模式和许多的高级功能,同时完全支持 JSM ...

  7. MRC-block与ARC-block

    上一篇已经讲解了MRC与ARC的基本知识,本篇我们讲解MRC-block与ARC-block的基本内容. 在MRC时代,Block会隐式地对进入其作用域内的对象(或者说被Block捕获的指针指向的对象 ...

  8. win10 git bash 闪退

    使用ghost重装了win10 专业版后.安装git,尝试重装了n个版本的git,右键git bash here 直接闪退,直接进入安装目录打开git-bash.exe依旧闪退, git右键点击Git ...

  9. permissions is only granted to system apps 错误

    permissions is only granted to system apps androidstudio中: File - Setting - Editor - Inspections, An ...

  10. 由AbstractQueuedSynchronizer和ReentrantLock来看模版方法模式

    在学完volatile和CAS之后,近几天在撸AbstractQueuedSynchronizer(AQS)的源代码,很多并发工具都是基于AQS来实现的,这也是并发专家Doug Lea的初衷,通过写一 ...