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

问题:假如有一个类似于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

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. javascript时间戳与日期格式之间的互转

    1. 将时间戳转换成日期格式 // 简单的一句代码 var date = new Date(时间戳); //获取一个时间对象 /** 1. 下面是获取时间日期的方法,需要什么样的格式自己拼接起来就好了 ...

  2. mybatis 批量更新 Parameter '__frch_item_0' not found. Available parameters are [list]

    一次在做批量更新数据的时候报错 Parameter '__frch_item_0' not found. Available parameters are [list] 记过反复查找,最后才发现是一个 ...

  3. performance数据

    // 获取 performance 数据 var performance = { // memory 是非标准属性,只在 Chrome 有 // 财富问题:我有多少内存 memory: { usedJ ...

  4. 成熟的 Git 分支模型

    个人博客原文: 成熟的 Git 分支模型 今天介绍一下工作中会用到的 Git 分支模型. 先贴上图以表敬意 闲言 在学校不管是自己写课程设计还是给老师做项目,有 2 到 3 个人一起协作开发时就会使用 ...

  5. AbstractQueuedSynchronizer源码分析(ReentrantLock锁的实现)

    1.  前言 Java中好多地方用到AbstractQueuedSynchronizer(PS:简称AQS),比如ReentrantLock.线程池,这部分在面试的时候也经常被问到,今天以Reentr ...

  6. Kibana安全特性之权限控制

    1.  前言 在之前的例子中,我们都是直接输入地址访问的,系统也没有提示我们要输入用户名密码.但是,在实际使用过程中不大可能所有人都是超级管理员可以做任何操作,一定是有权限控制的,这里我们借助X-Pa ...

  7. Python爬虫入门教程 10-100 图虫网多线程爬取

    图虫网-写在前面 经历了一顿噼里啪啦的操作之后,终于我把博客写到了第10篇,后面,慢慢的会涉及到更多的爬虫模块,有人问scrapy 啥时候开始用,这个我预计要在30篇以后了吧,后面的套路依旧慢节奏的, ...

  8. 一纸理解JVM

    JVM,JDK,JRE定义 JVM是Java Virtual Machine(Java虚拟机)的缩写. JDK是Java Development Kit JAVA语言开发工具箱(JAVA核心) JRE ...

  9. SpringBoot读取yml中的配置,并分离配置文件

    前言 在项目中经常遇到需要读取配置文件中的配置信息,这些配置信息之所以不写在代码中是因为实际项目发布或者部署之后会进行更改,而如果写在代码中编译之后没有办法进行修改. 之前使用的是properties ...

  10. Asp.Net SignalR Hub集线器

    集线器Hub类 使用持久连接类去开发是有些困难的,因为基于事件的开发方式,我们可以进行操作的地方也仅仅只是OnReceived事件内,这有些像websocket的方式.我们迫切的需要一种更人性化,更为 ...