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

问题:假如有一个类似于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. pytorch学习:准备自己的图片数据

    图片数据一般有两种情况: 1.所有图片放在一个文件夹内,另外有一个txt文件显示标签. 2.不同类别的图片放在不同的文件夹内,文件夹就是图片的类别. 针对这两种不同的情况,数据集的准备也不相同,第一种 ...

  2. shell的exec命令

    工作中遇到运维人员挂supervisor的时候建议启动使用命令control.sh start, 并且在control.sh 里面启动命令: exec -c ./bin/xxx -f config/x ...

  3. Bootstrap之底层媒体查询

    <style> @media only screen and (min-width:1024px ) { #box{ display: flex; flex-direction: row; ...

  4. ASP.NET Core DI 手动获取注入对象

    ASP.NET Core DI 一般使用构造函数注入获取对象,比如在ConfigureServices配置注入后,通过下面方式获取: private IValueService _valueServi ...

  5. 【ASP.NET Core快速入门】(十六)MVC开发:DbContextSeed初始化

    前言 由于我们现在每次EF实体模型变化的时候每次都是手动更改,我们想通过代码的方式让他自动更新,或者程序启动的时候添加一些数据进去 DbContextSeed初始化 首先,在Data文件夹下添加一个A ...

  6. spring-boot-2.0.3源码篇 - pageHelper分页,绝对有值得你看的地方

    前言 开心一刻 说实话,作为一个宅男,每次被淘宝上的雄性店主追着喊亲,亲,亲,这感觉真是恶心透顶,好像被强吻一样.........更烦的是我每次为了省钱,还得用个女号,跟那些店主说:“哥哥包邮嘛么叽. ...

  7. Linux和Shell回炉复习系列文章总目录

    本页内容都是本人回炉Linux时整理出来的.这些文章中,绝大多数命令类内容都是翻译.整理man或info文档总结出来的,所以相对都比较完整. 本人的写作方式.风格也可能会让朋友一看就恶心到直接右上角叉 ...

  8. xshell连接虚拟机详解--技术流ken

    xshell连接虚拟机 第一步:网络模式更改为桥接模式 第二步:重启网络 [root@ken1 ~]# systemctl restart network 第三步:获取IP地址 输入命令ip a 第四 ...

  9. MySQL 笔记整理(1) --基础架构,一条SQL查询语句如何执行

    最近在学习林晓斌(丁奇)老师的<MySQL实战45讲>,受益匪浅,做一些笔记整理一下,帮助学习.如果有小伙伴感兴趣的话推荐原版课程,很不错. 1) --基础架构,一条SQL查询语句如何执行 ...

  10. JS输入框去除负号(限定输入正数)

    onkeyup="(this.v=function(){this.value=this.value.replace(/\-/g,\'\');}).call(this)" 示例: & ...