Overloaded operators
Restrictions
- Only existing operators can be overloaded.
- Operators must be overloaded on a class or enumeration type
Overloaded operators must
- Preserve number of operands
- Preserve precedence
- Just a function with an operator name!
- Use the
operator
keyword as a prefix to nameoperator *(...)
- Use the
Member Functions
- Implicit first argument
- Developer must have access to class definition
- Members have full access to all data in class
- No type conversion performed on receiver(The number before the operator is receiver)
The prototypes of operators
+-*/%^&|~
const T operatorX(const T& l, const T& r) const;
! && || < <= == >= >
bool operatorX(const T& l, const T& r) const;
[]
T& T::operator[](int index)
.........
operator ++ and --
- postfix forms take an int argument -- compiler will pass in 0 as that int
class Integer{
public:
const Integer& operator++(); //prefix++
const Integer operator++(int); //postfix++
const Integer& operator--(); //prefix--
const Integer operator--(int); //postfix--
};
const Integer& Integer::operator++(){
*this += 1;
return *this;
}
//int argument not used so leave unnamed so won't get compiler warnings
//int参数未使用,因此保留未命名,因此不会收到编译器警告
const Integer Integer::operator++(int){
Integer old(*this);
++(*this);
return old;
}
Relational operators
- implement != in terms of ==
- implement >, >=, <= in terms of <
class Integer{
public:
bool Integer::operator==( const Integer& rhs ) const;
bool Integer::operator!=( const Integer& rhs ) const;
bool Integer::operator< ( const Integer& rhs ) const;
bool Integer::operator> ( const Integer& rhs ) const;
bool Integer::operator>=( const Integer& rhs ) const;
bool Integer::operator<=( const Integer& rhs ) const;
};
- Function prototype:
bool Integer::operator==( const Integer& rhs ) const{
return i == rhs.i;
}
//implement lhs != rhs in terms of !(lhs == rhs)
bool Integer::operator!=( const Integer& rhs ) const{
return !(*this == rhs);
}
bool Integer::operator< ( const Integer& rhs ) const{
return i < rhs.i;
}
//implement lhs > rhs in terms of lhs < rhs
bool Integer::operator> ( const Integer& rhs ) const{
return rhs < *this;
}
//implement lsh <= rhs in terms of !(lhs < rhs)
bool Integer::operator<=( const Integer& rhs ) const{
return !(rhs < *this);
}
//implement lsh >= rhs in terms of !(lhs < rhs)
bool Integer::operator>=( const Integer& rhs ) const{
return !(*this < rhs);
}
从函数原型可知,6个关系运算符都由小于和等于演变而成,若要修改较为方便。
operator []
- Must be a member function
- Single argument
- Implies that the object it is being called for acts like an array, so it should return a reference
operator =
T& T::operator=(const T& rhs){
//check for self assignment
if(this != &rhs){
//perform assignment
}
return *this;
}
- For classes with dynamically allocated memory declare an assignment operator (and a copy constructor)
- To prevent assignment, explicitly declare operator= as private
Value classes
- new key word : explicit
class One{
public:
One(){}
};
class Two{
public:
//Two(const One&) {}
explicit Two(const One&) {}
};
void f(Two) {}
int main()
{
One one;
//f(one); No auto conversion allowed
f(Two(one)); //OK -- user performs conversion
}
examples:
实现自己的MyString类(源码)https://github.com/Mered1th-Wang/Cpp-Learning/tree/master/20190520/MyString
Reference: