Intger num(2);
num++;
++num;
对自增运算符的重载要区分前置和后置。在重载之前需要思考一个问题,num++是返回一个临时变量还是num对象的本体。
为了解决这个问题可以考虑实现一个Inc_()函数和_Inc()函数分别模仿后置++和前置++的行为
Integer Inc_(){
int t=this->_num;
this->_num+=1;
return Integer(t);
}
Integer& _Inc(){
this->_num++;
return *this;
}
分别调用这两个函数
Integer num(3);
auto t=num.Inc_();
std::cout<<t.getValue();
Integer num(3);
auto t=num._Inc();
std::cout<<t.getValue();
通过这个例子不难看出后置++返回的是临时对象,前置++返回的是本体。
接下来就开始重载前置++和后置++
Integer operator++(){//后置++
int t=this->_num;
this->_num+=1;
return Integer(t);
}
Integer& operator++(){//前置++
this->_num++;
return *this;
}
但是如果这样写就会报错,因为函数重载是通过参数列表进行区分的,而不是通过返回值类型进行区分。
通常对于后置++要使用站位参数
Integer operator++(int){//后置++
int t=this->_num;
this->_num+=1;
return Integer(t);
}
bool operator&&(const Integer&right)const
{
return this->_num&&right._num;
}
std::cout<<std::boolalpha<<(Integer(0)&&Integer(1));
Integer operator -(){
return Integer(-this->_num);
}
重载了这运算符,对象就有了函数的行为(仿函数)
class Program
{
public:
void operator()(){//第一个括号是运算符
std::cout<<"hello world";
}
};
Program p;
p();//调用括号运算符
重载括号运算符是可以有参数的
class Program
{
public:
void operator()(int i){//第一个括号是运算符
std::cout<<"i="<<i<<"hello world";
}
};
class String
{
private:
int size;
char*str;
public:
String(const char*str)
{
size=strlen(str);
this->str=new char[size+1]{0};
strcpy(this->str,str);
}
int Size(){return size;}
};
int main()
{
String str="hello world";
return 0;
}
假设现在要有这样的一个操作
//循环遍历str内部的字符串
for(int i=0;i<str.Size();i++)
{
//to do
}
这个时候如何重载了下标访问运算符就可以通过str[i]遍历内部的字符串,这样操作是不是就相当方便了
char& operator[](int i){
return str[i];
}
说明
int main()
{
int*a=new int[5];
return 0;
}
上面的这个程序进行new操作后没有delete会造成内存泄漏,但如果就是忘掉了delete呢?这个可以通过自己实现一个类来解决这个问题。
class Auto_Ptr
{
public:
Auto_Ptr(int*ptr):m_ptr(ptr){}
~Auto_Ptr(){delete m_ptr;}
private:
int*m_ptr;
};
int*a=new int[5];
Auto_Ptr pa(a);
Auto_Ptr这个类帮我们完成了delete操作,这样就不用担心new了之后忘记delete了。
那么如何让Auto_Ptr则个类更像指针,那么就要重载一些运算符
class People
{
private:
int age_;
std::string name_;
public:
People(const std::string name,int age)
:name_(name),age_(age)
{}
std::string name()const{return name_;}
};
class Auto_Ptr
{
public:
Auto_Ptr(People*ptr):m_ptr(ptr){}
~Auto_Ptr(){delete m_ptr;}
People *operator->(){
return m_ptr;
}
People *operator&(){
return m_ptr;
}
People operator*(){
return m_ptr[0];
}
private:
People*m_ptr;
};
总的来说,虽然运算符重载提供了很大的灵活性,但是需要谨慎使用,以避免引入不必要的复杂性。在重载运算符时,应该尽量保持原有的语义和语法规则,以确保代码的可读性和可维护性。