c/c++ 重载运算符 ==和!=的重载
重载运算符 ==和!=的重载
问题:假如有一个类似于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;
}
}
c/c++ 学习互助QQ群:877684253
本人微信:xiaoshitou5854
c/c++ 重载运算符 ==和!=的重载的更多相关文章
- 【STL】重载运算符
重载运算符 为什么要重载运算符: C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如结构体),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予 ...
- 【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;偶数步 ...
- c++的重载运算符
c++中允许重载运算符: 这是我辛苦的结果 #include"iostream"using namespace std;class aaa{ int x;public: aaa() ...
- C# 重载运算符
如果你想让自己定义的类型可以用运算符进行运算,那么可以通过重载运算符来实现: 示例: class Salary { public int RMB { get; set; } public static ...
- c++中有些重载运算符为什么要返回引用
事实上,我们的重载运算符返回void.返回对象本身.返回对象引用都是可以的,并不是说一定要返回一个引用,只不过在不同的情况下需要不同的返回值. 那么什么情况下要返回对象的引用呢? 原因有两个: 允许进 ...
- C++ Primer : : 第十四章 : 重载运算符与类型转换之类型转换运算符和重载匹配
类型转换运算符 class SmallInt { public: SmallInt(int i = 0) : val(i) { if (i < 0 || i > 255) throw st ...
- C++ Primer : 第十四章 : 重载运算与类型转换之重载运算符
重载前须知 重载运算符是特殊的函数,它们的名字由operator和其后要重载的运算符号共同组成. 因为重载运算符时函数, 因此它包含返回值.参数列表和函数体. 对于重载运算符是成员函数时, 它的第一个 ...
- Swift开发第六篇——操作运算符也可以重载& func 的参数修饰
本篇分为两部分: 1.Swift 中重载操作运算符的使用 2.Swfit 中 func 的参数修饰 1.Swift 中重载操作运算符的使用 与别的语言不同,Swift 支持运算符的重载,运算符指的是“ ...
- C#基础知识系列一(goto、i++、三元运算符、ref和out、String和string、重载运算符)
前言 这两天在网上看到的总结很多,尤其是博客园中的,很多很多,也给了我很多的启发,当然自己也总结过,而且有很多人也给与我一些意见和看法.不管怎样,自己还是先把所谓的基础知识加强巩固下吧. 2014年的 ...
随机推荐
- 巡风源码阅读与分析---view.py
巡风xunfeng----巡风源码阅读与分析 巡风是一款适用于企业内网的漏洞快速应急.巡航扫描系统,通过搜索功能可清晰的了解内部网络资产分布情况,并且可指定漏洞插件对搜索结果进行快速漏洞检测并输出结果 ...
- Python——day11 函数(对象、名称空间、作用域、嵌套、闭包)
一.函数对象 函数名就是存放了函数的内存地址,存放了内存地址的变量都是对象,即 函数名 就是 函数对象 函数对象的应用 1. 可以直接被引用 fn = cp_fn 2 .可以当作函数参数传递 c ...
- Python内置函数(51)——property
英文文档: class property(fget=None, fset=None, fdel=None, doc=None) Return a property attribute. fget is ...
- Python爬虫入门教程 35-100 知乎网全站用户爬虫 scrapy
爬前叨叨 全站爬虫有时候做起来其实比较容易,因为规则相对容易建立起来,只需要做好反爬就可以了,今天咱们爬取知乎.继续使用scrapy当然对于这个小需求来说,使用scrapy确实用了牛刀,不过毕竟本博客 ...
- Python爬虫入门教程 30-100 高考派大学数据抓取 scrapy
1. 高考派大学数据----写在前面 终于写到了scrapy爬虫框架了,这个框架可以说是python爬虫框架里面出镜率最高的一个了,我们接下来重点研究一下它的使用规则. 安装过程自己百度一下,就能找到 ...
- oracle数据库之plsql可视化操作建表
首先登录PL/SQL developer. 点击工具栏中的第一个图标,选择“表”. 右边会弹出一个窗口,我们以可视化方式来创建一个Table. 如下图所示,在“一般”选项卡中,输入“名称” ...
- JavaScript面向对象--多态
一.多态的概念 相同的函数作用于不同的对象,会得到不同的结果,这就是多态. 二.如果不用多态,会怎么样? 这里有个浅显易懂的例子,定义一个函数叫makeSound,传入不同的对象,函数体里要写不同的情 ...
- Chapter 4 Invitations——12
"I don't know what you mean," I said, my voice guarded. “我不知道你什么意思”我声音谨慎地说道. "It's be ...
- 如何设计一个 RPC 系统
本文由云+社区发表 RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高.但是RPC本身的构成却比较复杂,由于受到编程语言.网络模型 ...
- Spring之事件监听(观察者模型)
目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...