C++ 操作符重载、友元、类型转换操作符、五种类型转换、函数操作符(一)

=====================================================================

算数操作符:+-*/%
关系操作符:><==
逻辑操作符:&& || !
位操作符:&、|、~、^
下标操作符:[]
取地址操作符:&
解引用操作符:*
插入操作符:<<
提取操作符:>>
取内存大小操作符:sizeof()

一、操作符与操作符函数

1. 将一个操作符标记#应用于一个或多个类类型的操作数时,编译器将调用这个操作符标记相关联的操作符函数operator#()。

实例:
=      -> operator=()
+      -> operator+()
>>    -> operator>> ()
[]      -> operator[] ()

...

2. 操作符函数的重载定义通常包括全局函数和成员函数两种形式。

 

二、输入输出操作符

1. 一般而言,如果一个输入输出操作#已经按照全局函数的方式被重载定义了,那么表达式
L#R;
将被编译器解释为如下函数调用:
operator# (L, R);

 可见,按照全局函数方式被重载定义的输入输出操作符函数,应
 该有两个参数,分别代表左操作数和右操作数;
 1>
 ostream& operator<<(ostream& os,const X&x){
  os<<x.xxx;
  ...
  return os;
 }

 istream& operator>>(istream& is,X&x){
  is>>x.xxx;
  ...
  return is;
 }

    friend ostream& <<operator(ostream&os,const Test&test){}
    friend istream& >>operator(istream&is,Test&test){}

2> 为了能够在全局操作符函数中直接访问类的私有成员,可以将该 操作符函数声明为类的友元;
3> 友元声明可以出现在一个类的任何部分(公,保,私),它允许被声明者直接访问该类的所有数据成员和成员函数,无论其访问属性如何;

三、双目操作符

1.L#R->L.operator#(R)
2.左右操作数在操作过程中不发生变化,返回的新对象,如+/-

 X X::operator#(const X&x)const{
  ...
  return X(...);
 }

3.右操作数不变,但左操作数改变,返回的是左操作数本身,而非仅
 是其值;

 X& X::operator#(const X&x){
  ...
  return *this;
 }

四、单目操作符

1.#O->O.operator#();

 操作数不变,返回新对象;
 X X::operator#(void)const{
  ...
  return X(...);
 }

2.自增减操作符
 1>操作数会发生变化;
 2>前缀表达式的值是改变以后的值,后缀表达式的值是改变以前的值;
 3>前缀表达式的值是操作数本身(引用)可以连用;后缀运算不能连用,
  会出现编译错误;
 4>区分前后缀;-----哑元
  ++c;   //c.operator()
  c++;   //c.operator(0)   //利用重载区分前后缀;

金典实例:

#include <iostream>
using namespace std;
class Complex {
public:
    Complex (double fReal = 0.0, double fImag = 0.0) : m_fReal (fReal), m_fImag (fImag) {}
    Complex operator+ (const Complex& c) const {
        double fReal = m_fReal + c.m_fReal;
        double fImag = m_fImag + c.m_fImag;
        Complex sum (fReal, fImag);
        return sum;
    }
    Complex operator+ (double fReal) const {
        return Complex (m_fReal + fReal, m_fImag);
    }
    Complex operator- (const Complex& c) const {
        return Complex (m_fReal - c.m_fReal, m_fImag - c.m_fImag);
    }
    Complex& operator+= (const Complex& c) {
        m_fReal += c.m_fReal;
        m_fImag += c.m_fImag;
        return *this;
    }
    Complex& operator-= (const Complex& c) {
        m_fReal -= c.m_fReal;
        m_fImag -= c.m_fImag;
        return *this;
    }
    Complex operator- (void) const {
        return Complex (-m_fReal, -m_fImag);
    }
    // 前缀
    Complex& operator++ (void) {
        m_fReal++;
        m_fImag++;
        return *this;
    }
    Complex& operator-- (void) {
        m_fReal--;
        m_fImag--;
        return *this;
    }
    // 后缀
    const Complex operator++ (int) {
        Complex c = *this;
        m_fReal++;
        m_fImag++;
        return c;
    }
    const Complex operator-- (int) {
        Complex c = *this;
        m_fReal--;
        m_fImag--;
        return c;
    }
private:
    double m_fReal;
    double m_fImag;
    friend ostream& operator<< (ostream&, const Complex&);
    friend istream& operator>> (istream&, Complex&);
};
ostream& operator<< (ostream& os, const Complex& c) {
    return os << "(" << c.m_fReal << "+" << c.m_fImag << "i)";
}
istream& operator>> (istream& is, Complex& c) {
    return is >> c.m_fReal >> c.m_fImag;
}
int main (void) {
    Complex c1 (1, 2);
    cout << c1 << endl; // operator<< (operator<< (cout, c1), endl);
//    Complex c2;
//    cin >> c2; // operator>> (cin, c2);
//    cout << c2 << endl;
    Complex c3 (3, 4);
    Complex c4 = c1 + c3; // c1.operator+ (c3);
    cout << c1 << "+" << c3 << "=" << c4 << endl;
    cout << c4 << "-" << c3 << "=" << c4-c3<<endl;
//    int n1 = 10, n2 = 20;
//    cout << (n1 += n2) << endl;
//    cout << n1 << endl;
//    n1 += n2 += 30; // n1 += (n2 += 30);
//    cout << n1 << ", " << n2 << endl;
//    (n1 += n2) += 30;
//    cout << n1 << ", " << n2 << endl; // 60, 20
    Complex c2 (5, 6);
//    c1 += c2 += c3; // c1.operator+=(c2.operator+=(c3));
    (c1 += c2) += c3; // c1.operator+=(c2).operator+= (c3);
    cout << c1 << ", " << c2 << endl;
    cout << (c1-=c3) << endl;
    cout << -c1 << endl;
    /*
    int n = 100;
    cout << n++ << endl; // 100
    cout << n << endl; // 101
    n = 100;
    cout << ++n << endl; // 101
    cout << n << endl; // 101
    n = 100;
    ++++n; // ++(++n)
    cout << n; // 102
//    n++++; // 后自增不能连用
    */
    cout << endl;
    cout << c2 << endl;
    cout << ++c2 << endl;
    cout << c2 << endl;
    ++++c2;
    cout << c2 << endl;
    cout << endl;
    cout << c2++ << endl;
    cout << c2 << endl;
//    c2++++;
    cout << c2+100 << endl; // c2.operator+(100)
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以使用非友元函数来实现双目操作符重载,但需要注意一些细节问题。 首先,非友元函数不能直接访问类的私有成员,因此需要将双目操作符重载函数声明为类的成员函数或者将其声明为友元函数。 其次,如果将双目操作符重载函数声明为类的成员函数,则该函数的左操作数将自动绑定到调用该函数的对象上,而右操作数需要作为函数的参数传递。 如果将双目操作符重载函数声明为友元函数,则需要在函数内部访问类的私有成员,可以通过将该函数声明为类的友元函数来实现。 以下是一个示例代码,演示了如何使用非友元函数实现双目操作符重载: ```C++ #include <iostream> class Complex { public: Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {} Complex operator+(const Complex& other) const { return Complex(real + other.real, imag + other.imag); } double getReal() const { return real; } double getImag() const { return imag; } private: double real, imag; }; Complex operator-(const Complex& lhs, const Complex& rhs) { return Complex(lhs.getReal() - rhs.getReal(), lhs.getImag() - rhs.getImag()); } int main() { Complex c1(1.0, 2.0), c2(3.0, 4.0); Complex c3 = c1 + c2; Complex c4 = c1 - c2; std::cout << "c1 + c2 = " << c3.getReal() << " + " << c3.getImag() << "i" << std::endl; std::cout << "c1 - c2 = " << c4.getReal() << " + " << c4.getImag() << "i" << std::endl; return 0; } ``` 在上面的示例代码中,`operator-`函数被声明为一个非友元函数,并且直接访问了类的私有成员。在`main`函数中,我们使用`operator+`和`operator-`来进行复数的加减操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值