重載運算符 關係,下標,遞增減,成員訪問的重載 為了演示關係,下標,遞增減,成員訪問的重載,創建了下麵2個類。 1,類StrBlob重載了關係,下標運算符 2,類StrBlobPtr重載了遞增,抵減,成員訪問運算符 1,類StrBlob功能概要:類型與vector,但只能存放string類型的數據。 ...
重載運算符 關係,下標,遞增減,成員訪問的重載
為了演示關係,下標,遞增減,成員訪問的重載,創建了下麵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
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;
}
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
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;
}
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