重载运算与类型转换
一、运算符重载
-
基本概念
执行
a+b其实是隐形执行了operator+(a,b),隐形调用了一个函数a作为成员函数的时候执行运算符时,函数自带一个
this指针,因此函数只需要一个参数1
2
3
4
5
6
7
8
9StrVec& StrVec::operator=(const StrVec&s){
if(&s!=this){
auto newdata=alloc_n_copy(s.begin(),s.end());
free();
element=newdata.first;
first_free=newdata.second;
}
return *this;
}需要多个参数并且需要本身参数时。需要用到友元函数。例如:
1
2
3
4
5
6friend std::ostream& operator<<(std::ostream&os,const StrVec &s){
for(size_t i=0;i<s.size();i++){
os<<s[i]<<" ";
}
return os;
} -
不能重构的运算符
::.*.?: -
输入输出运算符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//重载<<
std::ostream &operator<<(std::ostream &os,const StrVec &s){
for(size_t i=0;i<s.size();i++){
os<<s[i]<<" ";
}
return os;
}
//重载>>
std::istream &operator>>(std::istream &is, StrVec &s){
std::string t;
is>>t;
if(is) s.push_back(t);
else s=StrVec();
return is;
} -
相等运算符
1
2
3
4
5
6
7bool operator==(const StrVec& lhs,const StrVec& rhs){
if(lhs.size()!=rhs.size()) return false;
for(size_t i=0;i<lhs.size();i++){
if(lhs[i]!=rhs[i]) return false;
}
return true;
} -
赋值运算符
1
2
3
4
5
6
7
8
9StrVec& StrVec::operator=(const StrVec&s){
if(&s!=this){
auto newdata=alloc_n_copy(s.begin(),s.end());
free();
element=newdata.first;
first_free=newdata.second;
}
return *this;
} -
下标运算符
1
2
3
4
5
6std::string& operator[](size_t index) {
return element[index]; // 返回元素的引用
}
const std::string& operator[](size_t index) const {
return element[index]; // 返回元素的常量引用(用于 const 对象)
}
二、function库
function可以用来绑定函数:
1 |
|
三、类型转换
-
类型转换符
一般形式:
1
operator type() const
例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class SmallInt{
pubilc:
SmallInt(int i=0): val(i){
if(i<0||i>255) throw std::out_or_range("bad");
}
operator int() cosnt {return val;}
private:
std::size_t val;
};
int main(){
Smallint si;
si=4;//4被隐式转换成Smallint ,然后给构造函数
si+3;//si隐式转换成int
} -
explicit关键字
隐式类型转换有可能带来问题,因此c11引入了explicit关键字,可以避免隐式转换。
1
2
3Smallint si=3;
si+3;//错误,声明了explicit后无法隐式转换
static_cast<int>(si) +3;//正确 -
static_cast
在c中类型转换一般直接
(type)变量来达到类型转换c++需要通过
static_cast<type> 变量来执行类型转换。