重载运算符 关系,下标,递增减,成员访问的重载

为了演示关系,下标,递增减,成员访问的重载,创建了下面2个类。

1,类StrBlob重载了关系,下标运算符

2,类StrBlobPtr重载了递增,抵减,成员访问运算符

1,类StrBlob功能概要:类型与vector,但只能存放string类型的数据。

2,类StrBlobPtr功能概要:类型指针,指向类StrBlob中的某个元素。

注意点:

1,->的重载方法的返回值必须是指针。

2,系统无法区分是前置的递增还是后置的,为了区分,在重载后置的时候,加一个int类型的参数,就告诉编译器这个是后置的递增。

3,后置的递增或者抵减的重载方法的返回值必须是值,不能是引用或者指针。因为返回的是值类型,所以会在retern处调用拷贝构造函数。前置的是放回引用,所以就不会调用拷贝构造函数。所以,能调用前置的时候,就调用前置的

StrBlob.h

#ifndef __STRBLOB_H__
#define __STRBLOB_H__ #include <memory>
#include <string>
#include <vector> class StrBlobPtr;
class StrBlob{
friend class StrBlobPtr;
friend bool operator==(const StrBlob&, const StrBlob&);
friend bool operator!=(const StrBlob&, const StrBlob&);
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob();
StrBlob(std::initializer_list<std::string>);
size_type size() const{return data->size();}
bool empty()const {return data->empty();}
void push_back(const std::string& t){data->push_back(t);}
void pop_back();
std::string& front();
std::string& back(); std::string& operator[](size_type);
const std::string& operator[](size_type)const; StrBlobPtr begin();
StrBlobPtr end(); private:
std::shared_ptr<std::vector<std::string>> data;
void check(size_type, const std::string&) const;
};
bool operator==(const StrBlob&, const StrBlob&);
bool operator!=(const StrBlob&, const StrBlob&); #endif

github

StrBlob.cpp

#include "StrBlob.h"
//#include <iostream>
#include "StrBlobPtr.h" StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()){}
StrBlob::StrBlob(std::initializer_list<std::string> il) :
data(std::make_shared<std::vector<std::string>>(il)){} void StrBlob::check(size_type i, const std::string& msg)const{
if(i >= data->size()){
throw std::out_of_range(msg);
}
} std::string& StrBlob::front(){
check(0, "front");
return data->front();
} std::string& StrBlob::back(){
check(0, "back");
return data->back();
} void StrBlob::pop_back(){
check(0, "pop_back");
data->pop_back();
}
bool operator==(const StrBlob& lhs, const StrBlob& rhs){
/*
if(lhs.data->size() >=0 && lhs.data->size() == rhs.data->size()){
for(int i = 0; i < lhs.data->size(); ++i){
if((*lhs.data)[i] != (*rhs.data)[i]){
return false;
}
}
return true;
}
else{
return false;
}
*/
return *lhs.data == *rhs.data; }
bool operator!=(const StrBlob& lhs, const StrBlob& rhs){
return !operator==(lhs, rhs);
} std::string& StrBlob::operator[](size_type idx){
return (*data)[idx];
}
const std::string& StrBlob::operator[](size_type idx)const{
return (*data)[idx];
} StrBlobPtr StrBlob::begin(){
auto b = StrBlobPtr(*this);
return b;
}
StrBlobPtr StrBlob::end(){
auto e = StrBlobPtr(*this, data->size());
return e;
}

github

StrBlobPtr.h

#ifndef __STRBLOBPTR_H__
#define __STRBLOBPTR_H__ #include <memory>
#include <string>
#include <vector>
#include "StrBlob.h" class StrBlob;
class StrBlobPtr{
public:
StrBlobPtr() : curr(0){}
StrBlobPtr(StrBlob& a, size_t sz = 0):wptr(a.data), curr(sz){} //方法get和重载*的效果是一样的
std::string get(){
auto ptr = check(curr, "get string value");
return (*ptr)[curr];
} //方法get和重载*的效果是一样的
std::string& operator*(){
auto p = check(curr, "get string value");
return (*p)[curr];
}
std::string* operator->(){
return & this->operator*();
} StrBlobPtr& operator++();
StrBlobPtr& operator--();
StrBlobPtr operator++(int);
StrBlobPtr operator--(int); private:
std::shared_ptr<std::vector<std::string>>
check(std::size_t, const std::string&) const; std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr;
}; #endif

github

StrBlobPtr.cpp

#include "StrBlobPtr.h"

std::shared_ptr<std::vector<std::string>>
StrBlobPtr::check(std::size_t i, const std::string& msg) const{
auto ptr = wptr.lock();
if(!ptr){
throw std::runtime_error("unbound StrBlobPtr");
}
if(i >= ptr->size()){
throw std::out_of_range(msg);
}
return ptr;
} //qianzhi
StrBlobPtr& StrBlobPtr::operator++(){
check(curr, "will past end");
++curr;
return *this;
}
//qianzhi
StrBlobPtr& StrBlobPtr::operator--(){
--curr;
check(curr, "will past begin");
return *this;
}
//houzhi
StrBlobPtr StrBlobPtr::operator++(int){
auto tmp = *this;
++*this;
return tmp;
}
//houzhi
StrBlobPtr StrBlobPtr::operator--(int){
auto tmp = *this;
--*this;
return tmp;
}

github

main方法

#include "StrBlob.h"
#include "StrBlobPtr.h"
#include <iostream> using namespace std;
int main(){
StrBlob s1{"11", "22"};
StrBlobPtr p1 = s1.begin();
StrBlobPtr tm = ++p1;
cout << tm->size() << endl;
p1--;
tm = p1;
cout << *tm << endl;
}

编译方法:

g++ -g StrBlob.cpp StrBlobPtr.cpp mainStrBlobPtr.cpp -std=c++11

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

本人微信:xiaoshitou5854

c/c++ 重载运算符 关系,下标,递增减,成员访问的重载的更多相关文章

  1. [C++ Primer] : 第14章: 重载运算符与类型转换

    基本概念 重载运算符是具有特殊名字的函数: 它们的名字由关键字operator和其后要定义的运算符号共同组成. 重载运算符函数的参数数量与该运算符作用的运算对象数量一样多. 对于二元运算符来说, 左侧 ...

  2. C++ 重载运算符(详)

    C++ 重载运算符 C 重载运算符 一重载函数 1例程 2备注 二重载运算符 11 二元运算符重载 11 一元运算符重载 111 -- 2备注 3 特殊运算符重载 31 号运算符 32 下标运算符 3 ...

  3. [C++] 重载运算符与类型转换(1)

      1.形式:返回值 operator符号(参数列表){}   2.不能被重载的运算符::: 作用域运算符  .*   . 成员访问运算符   ?: 条件运算符:某些运算符(逗号,,取地址&, ...

  4. 【C++】C++中重载运算符和类型转换

    输入输出运算符 输入输出运算符 输入输出运算符 算术和关系运算符 相等运算符 关系运算符 赋值运算符 复合赋值运算符 下标运算符 递增和递减运算符 成员访问运算符 函数调用运算符 lambda是函数对 ...

  5. C++重载运算符的规则

    (1)C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载. 例如,有人觉得BASIC中用“* *”作为幂运算符很方便,也想在C++中将“* *”定义为幂运算符,用“3* *5”表示3 ...

  6. 【c++习题】【17/5/8】重载运算符

    1.设计一个Complex(复数)类,完成如下要求: 该类具有实部(Real_Part)和虚部(Image_Part)通过重载运算符“+”实现两个复数的相加通过重载运算符“+”实现一个复数与一个数值的 ...

  7. C++重载运算符简单总结

    当运算符作用于类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义.明智的使用运算符重载能令我们的程序更易于编写和阅读. 一.基本概念 什么是运算符重载?重载的运算符是具有特殊名字的函数:它们 ...

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

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

  9. Chapter14:重载运算符

    对于一个运算符函数来说,它或者是类的成员,或者至少含有一个类类型的参数. int operator+(int, int);//错误,不能为int重定义内置运算符 对于一个重载的运算符来说,其优先级和结 ...

随机推荐

  1. Java数据结构和算法 - TreeMap源码理解红黑树

    前言 本篇将结合JDK1.6的TreeMap源码,来一起探索红-黑树的奥秘.红黑树是解决二叉搜索树的非平衡问题. 当插入(或者删除)一个新节点时,为了使树保持平衡,必须遵循一定的规则,这个规则就是红- ...

  2. PyCharm2019 激活码

    因公司的需求,需要做一个爬取最近上映的电影.列车号.航班号.机场.车站等信息,所以需要我做一个爬虫项目,当然java也可以做爬虫,但是还是没有python这样方便,所以也开始学习Python啦!!! ...

  3. 『离散化 discrete』

    离散化(discrete) 离散化可以说是一个很基础的算法吧,但是有些时候还是很好用很有必要的算法. 离散化的排序的一个运用,具体地讲,离散化算法是将无穷大集合中的若干个元素映射到有限大小的集合中,以 ...

  4. google的GCM推送使用简介

    pom <!-- https://mvnrepository.com/artifact/com.google.gcm/gcm-server --> <dependency> & ...

  5. docker 复制镜像和复制容器

    复制镜像和复制容器都是通过保存为新镜像而进行的. 具体为: 保存镜像 docker save ID > xxx.tar docker load < xxx.tar 保存容器 docker ...

  6. JDK源码分析(1)之 String 相关

    ​在此之前有无数次下定决心要把JDK的源码大致看一遍,但是每次还没点开就已被一个超链接或者其他事情吸引直接跳开了.直到最近突然意识到,因为对源码的了解不深导致踩了许多莫名其妙的坑,所以再次下定决心要把 ...

  7. [二]基础数据类型之Long详解

      Long   Long 基本数据类型long  的包装类 Long 类型的对象包含一个 long类型的字段     属性简介   值为  263-1 的常量,它表示 long 类型能够表示的最大值 ...

  8. HDFS架构及原理

    原文链接:HDFS架构及原理 引言 进入大数据时代,数据集的大小已经超过一台独立物理计算机的存储能力,我们需要对数据进行分区(partition)并存储到若干台单独的计算机上,也就出现了管理网络中跨多 ...

  9. javascript基础修炼(11)——DOM-DIFF的实现

    目录 一. 再谈从Virtual-Dom生成真实DOM 二. DOM-Diff的目的 三. DOM-Diff的基本算法描述 四. DOM-Diff的简单实现 4.1 期望效果 4.2 DOM-Diff ...

  10. MySQL 笔记整理(9) --普通索引和唯一索引,应该怎么选择?

    笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 9) --普通索引和唯一索引,应该怎么选择? 假如你在维护一个市民系统, ...