码迷,mamicode.com
首页 > 其他好文 > 详细

重载运算符

时间:2018-05-19 22:35:14      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:参数表   析构   完全   mes   type   public   直接   friend   参数   

一、特殊运算符的重载
1. 取值运算符:*    "指针解引用运算符"
  1)作用:让一个对象模拟指针的行为
  2)重载方式:
  <1>成员函数方式
  class A

  {
    B & operator * (void) const {...}
  };
  <2>友元函数方式
  class A

  {
    friend B & operator * (const A & rhs) {...}
  };

  

#include <iostream>
using namespace std;

class B
{
  public:
  B(): b1(1), b2(2)
  {
    cout << "B()\n";
  }
  ~B()
   {
    cout << "~B()\n";
    }   
  public:
  int b1;
  int b2;
  // int b[1000000]; //stack只有8M多,栈会放不下,必须new出内存存放
};

class AutoPtr
{
  public:
  AutoPtr(B *p): m_p(p) {}
  ~AutoPtr()
  {
    delete m_p; m_p = NULL;
  }
  B &operator *() const
  { //取值运算符 * 实现
    return *m_p; //让*ap返回new出的一个B类型的对象
  }
  private:
  B *m_p;
};

int main()
{
  AutoPtr ap(new B);
  cout << (*ap).b2 << endl;

  /*B * pb = new B;
  cout << "*(pb).b1 = " << (*pb).b1 << endl;
  cout << "pb->b2 = " << pb->b2 << endl;
  */
  return 0;
}

2. 取值运算符:->
  1)作用:让一个对象模拟指针的行为
  2)方式:
  <1>成员函数方式
  class A

   {
    B * operator -> () const {...}
  };

#include <iostream>
using namespace std;
class B
{
  public:
  B(): b1(1), b2(2)
  {
    cout << "B()\n";
  }
  ~B()
  {
    cout << "~B()\n";
  }
  public:
    int b1;
    int b2;
};

class AutoPtr
{
public:
  AutoPtr(B *p): m_p(p) {}
  ~AutoPtr()
  {
    delete m_p;
    m_p = NULL;
  }
  B & operator * () const
  {
    return *m_p;
  }
  B *operator -> () const
  { //取值运算符 -> 实现
    return m_p;
  }
  private:
  B *m_p;
};

int main()
{
  AutoPtr ap(new B);
  cout << (*ap).b1 << endl; //1
  cout << ap->b2 << endl; //2
  return 0;
}


3. 函数操作运算符: ()

  如何重载()运算符   还是一样的三部曲
    1.承认是函数 写出调用原型 f.operator()(3, 4);
    2.根据原型 在类 F 中写出(函数名为operator()的)成员函数
    3.使用重载后的运算符


  1)作用:重载函数操作运算
  2)方式:
  <1>只能以成员函数方式重载
  class A

  {
    返回类型 operator () (形参表) {...}
  };
  3)说明:
  <1>只能以成员函数方式重载
  <2>通常重载了"()"运算符的对象能像函数一样调用,我们把这样的对象叫做"函数对象",(lambda表达式的用法来源于函数对象),也叫仿函数
  <3>该运算符中的形参表可以自定义("C++语言当中唯一一个参数表可变的运算符重载方式")
  <4>该运算符中的形参可以有"默认实参"
  <5>该运算符重载的成员函数的"返回类型也可自定义"

#include <iostream>
using namespace std;
class Sum

{
  public:
  Sum(): m_sum(0) {}
  int operator () (int a, int b, int c = 0, int d = 0) 

  {

    int s = a+b+c+d;
    m_sum += s; //把每次调用的实参全部放在成员变量里做统计
    return s;
  }
  int getTotal() const
  {
    return m_sum;
  }
  private:
    int m_sum;
};

int main()
{
  Sum s; //函数对象
  int a = s(100, 200, 300, 400);
  cout << "a = " << a << endl; //1000
  a = s(500, 600);
  cout << "a = " << a << endl; //1100   
  a = s(700, 800, 900);
  cout << "a = " << a << endl; //2400
  cout << s.getTotal() << endl; //4500
  return 0;
}

4. 自定义类型转换运算符
  1)作用:实现自定义的类型到其他类型(基础数据类型)的转换
  2)方式:
  <1>常成员函数方式
  operator TYPE () const {}
  <2>普通成员函数方式
  operator TYPE () {}
  3)说明:不能以友元函数方式重载。

  #include <iostream> 

  using namespace std;
  class Number
  {
    public:
      Number(double a = 0): m_data(a) {}
      operator int () const
      {
        return m_data;
      }
   public:
    double  m_data;
};
int main(void)
{
  Number n1(100.222);
  int i = n1; //类型转换,不重载类型转换运算符此处会报错
  cout<<"n1.m_data= " << n1.m_data<< endl;
  cout<<"i = " << i << endl;
  cout<<"n1= "<<n1<<endl;
  return 0;
}

5. new/delete 运算符重载
  1)作用:特殊场合手动管理创建的内存和释放的内存
  2)方式:
  <1>只能以静态成员函数的方式重载
  class A

  {
    static void * operator new (size_t size) { ... }
    static void operator delete (void *p) { ... }   
  };
  <2>只能以静态成员函数的方式重载 "new[]/delete[]"
  class A

  {
    static void * operator new[] (size_t size) { ... }
    static void operator delete[] (void *p) { ... } 
  };
  3)说明:
  <1>在重载 new/delete 时,不能使用 this 指针
  <2>如果用户没有指定 static 编译器也会为其添加 static

#include <iostream>
#include <stdlib.h>
using namespace std;
class A
{
  public:
  //以下两个静态成员函数将在动态分配和释放单个对象时调用
  static void * operator new (size_t size)
  {
    cout << "malloc(size): " << size << endl;
    return malloc(size);
  }
  static void operator delete (void *p)
  {   
    cout << "free(p): " << p << endl;
    free(p);
    p = NULL;
  }

  //以下两个静态成员函数将在动态创建和销毁数组时调用
  static void * operator new[] (size_t size)
  {
    cout << "分配数组size = " << size << endl;
    return malloc(size);
  }
  static void operator delete[] (void *p)
  {
    cout << "释放数组free(p): " << p << endl;
    free(p);
    p = NULL;
  }
  ~A()
  {
    cout << "析构~~~" << endl;
  }
  private:
    double m_d; //double 8 字节
};

int main()
{
  //分配静态对象
  A *pa = new A; //new 调用成员函数重载new
  cout << "pa ------> " << pa << endl;
  delete pa; //delete 调用成员函数重载delete
  pa = NULL;
  cout << endl;

  //动态分配数组
  pa = new A[2];   
  cout << "pa ------> " << pa << endl;
  delete [] pa;
  pa = NULL;
  return 0;
}

【运算符重载小结】
1. 以下 6 个运算符不能重载:
1)作用域运算符  ::
2)直接成员访问运算符  .
3)成员指针解引用运算符  .*
4)条件运算符  ? :
5)字节长度运算符  sizeof
6)类型信息操作符  typeid (后续补充)
2. 以下 4 个只能以成员函数方式重载:
1)operator []
2)operator =
3)operator ->
4)operator ()
3. 运算符重载说明:
1)只能在原有的运算符上进行重载,不能增加运算符;
+++  //不可以!
2)运算符的重载不能改变运算符的优先级;
3)运算符重载无法改变运算符操作数的个数,"()"运算符除外;
4)完全是基础数据类型的运算符无法被重载;

补充:(成员指针解引用运算符)

1 成员变量指针
1)定义
类型 类名::*成员指针变量名 = &类名::成员变量;
2)使用
   对象.*成员指针变量名;
   对象指针->*成员指针变量名;
 ".*":成员指针解引用运算符
 "->*":间接成员指针解引用运算符
注:成员变量指针的本质是类中特定成员在对象中的相对地址。
2 成员函数指针
虽然成员函数并不存储在对象中,但也要通过对象或者对象指针对成员函数指针解引用,其目的只有一个,即提供this指针 1)定义 返回类型 (*类名::成员函数指针)(形参表) = &类名::成员函数名; 2)使用 (对象.*成员函数指针)(实参表); (对象指针->*成员函数指针)(实参表);


#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
class Student
{
  public:
    Student(const string & name = "",int age = 0):m_name(name),m_age(age){}
    string m_name;
    int m_age;
    static int m_data;
    static int add(int x , int y)
    {
      return x+y;
    }
    void who()
    {
      cout << m_name << " "
        << m_age << endl;
    }
};
int Student::m_data = 100;
int _tmain(int argc, _TCHAR* argv[])
{//成员变量指针
  string Student::*pname = &Student::m_name;//pname的初始化不需要对象,他将指向任何对象的m_name
  //存成员变量的偏移量,在解引用时,使用起始位置+偏移量

  int Student ::*page = &Student::m_age;
  Student s1("张飞",24),s2("赵云",25);
  //成员函数指针
  void (Student::*pwho)(void) = &Student::who;
  //成员指针时,取地址必须写
  cout << s1.*pname << endl;//(.*,成员指针解引用运算符->*间接成员指针解引用运算符)
  cout << s2.*pname <<endl;
  cout << s1.*page << endl;
  cout << s2.*page << endl;
  (s1.*pwho)();
  (s2.*pwho)();
  
  int *pdata = &Student::m_data;
  cout << *pdata << endl;
  int(*padd)(int ,int ) = Student ::add;
  cout << padd(100,200) << endl;

  system("pause");
  return 0;
}

 

重载运算符

标签:参数表   析构   完全   mes   type   public   直接   friend   参数   

原文地址:https://www.cnblogs.com/tianzeng/p/9061736.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!