美文网首页
[陈宗权C++]C++第4天PM--运算符重载

[陈宗权C++]C++第4天PM--运算符重载

作者: Optimization | 来源:发表于2020-01-31 00:51 被阅读0次

参考:

重点:

  • 智能指针模拟,计数器
    运算符重载
  • operator->
  • operator*
  • ++a ,a++,--a ,a--运算符
  • operator=
  • operator[]
  • operator()
  • operator double()
  • operator bool()
  • 函数对象
  • 静态数据成员
  • const
  • 引用

注意:

  • 如果有指针类型的类,自己写拷贝构造函数,自己写赋值运算符函数,自己写析构!!!!

正文:

////达内C++教程\03_标准C++编程_陈宗权_7day\标准C++编程_day04PM_运算符重载 TEST1
//#include <iostream>
//#include <string>
//using namespace std;
//
////.*、 .、 三目运算符? :、不能重载
////:: 不能重载
//// == 、 -> 、[] () (类型) 只能用成员函数
//// 运算符首先考虑弄成成员函数
//// T* operator->()   只能无参数,返回对象的地址
//// x->y  x.operator->() 封装类型,模仿指针
//
//
//class F {
//
//  F operator!()const;
//};
//
//// 临时对象也是对象!!!
//// 只会调用构造函数,不会调用复制构造函数,因为编译做了优化。
//F F::operator!() const
//{
//  return F();
//}
//
//struct date {
//  int year;
//  int month;
//  int day;
//};
//struct Person {
//  string name;
//  int age;
//  bool gender;
//  double salary;
//  date birth;
//
//  Person() { cout <<"创建Person对象在"<<this << std::endl; }
//  ~Person() { cout << "释放Person对象在" << this << std::endl; }
//};
//
//
//class autoptr {
//  Person* p;
//  static int cnt;//大家共用1个计数器
//public:
//  autoptr(Person* p) :p(p) { ++cnt; }
//  autoptr(const autoptr& a) :p(a.p) { ++cnt; }
//  ~autoptr() { std::cout <<cnt<<":" << std::endl; if (--cnt == 0) delete p; }
//  Person* operator->() { return p; }
//  Person& operator*() { return *p; }
//};
//
////静态数据成员在类外初始化
//int autoptr::cnt = 0;
//
//int main()
//{
//  //a指针
//  //Person* a = new Person;
//  autoptr b(new Person);//或者autoptr b= new Person;
//  
//  autoptr c = b;//初始化,调用复制构造,2个都会析构,第二个析构就会有问题,对指针进行计数,最一个后才进行delete
//  autoptr d = b;
//  std::cout << b->age << std::endl;
//  b->name = "furong";//b.operator->()->name
//  std::cout <<(*b).name << std::endl;
//  (*b).birth.year = 1985;
//  std::cout << b->birth.year << std::endl;
//  c = b;//赋值运算符
//  system("pause");
//
//}

//问题1:
// 赋值运算符,会原样复制,计数器没有加1。析构不会有问题。
// 答:析构有问题是因为多次delete,而我不会多次delete是因为我用了计数器,因为多个对象的数据指针类型成员指向同一块地址
// 


////达内C++教程\03_标准C++编程_陈宗权_7day\标准C++编程_day04PM_运算符重载 TEST2
//#include <iostream>
//#include <string>
//using namespace std;
//
//class Stack {
//  typedef unsigned int uint;
//  string* mem;
//  uint max;
//  uint len;
//public:
//  Stack(uint n):mem(new string[n]),max(n),len(0) {}
//  Stack(const Stack& s) :mem(new string[s.max]),max(s.max),len(s.len) {}//新分配内存空间就不会有问题
//  uint max_size() const { return max; }
//  uint size() const { return len; }
//  Stack& push(const string& e) { if (len >= max) throw 0; mem[len++] = e; return *this; };
//  string pop() { if (len == 0) throw 1; return mem[--len]; }
//  void print()const { for (uint i = 0; i < len; i++) cout << mem[i]; cout << endl; }
//  //去想
//  Stack& operator=(const Stack& rh) {
//      if (this == &rh) return *this; //考虑自己给自己赋值的情况
//      delete[] mem;
//      mem = new string[rh.max];
//      for (uint i = 0; i < len; i++) { mem[i] = rh.mem[i]; }
//      return *this;
//  }
//
//  ~Stack() { delete[] mem; }
//
//};
////如果有指针类型,自己写拷贝构造函数,自己写赋值运算符函数,自己写析构!!!!
//
//
//int main()
//{
//  Stack s1(5);
//  Stack s2(8);
//  Stack s3(s1);//new一块地方,析构会有问题,重复释放同一块内存,导致
//  s1.push("1").push("2").push("3").push("4");
//  s1.print();
//  s2.push("yangqiang").push("furong");
//  s2.print();
//  s1 = s2;//析构有问题,赋值之后,2个对象的成员又一样了,s1.operator=(s2)
//  s3.print();
//
//  //
//  s2 = s2;
//
//  system("pause");
//}
//









////TEST3
////++a (前++)
////T& operator++(T& a) 非成员
////T& operator++()     成员
//
////a++,(后++) 加个形参,这个形参称为哑元
////T operator++(T& a, int)  非成员
////T operator++(int)        成员
//
////对自定义类型,要用前++ ,因为效率高,少了一些
//#include <iostream>
//using namespace std;
//
//class F {
//  int n;
//  int d;
//public:
//  F(int n = 0, int d = 1) :n(n), d(d) {}
//  friend ostream& operator<<(ostream& o, const F& f) {
//      cout <<f.n<<"/"<<f.d << endl;
//      return o;
//  }
//  F& operator++() { n += d; return *this; }
//  F operator++(int) { F old(*this); n += d; return old; };
//  friend F& operator--(F& f) { f.n -= f.d; return f; }
//  friend F operator--(F& f, int) { F old(f); f.n -= f.d; return old; }
//
//  operator double() { return 1.0*n / d; }
//  operator bool() { return n != 0; }
//};
//
//void func1(F a) { cout <<a << endl; }
//
//int main()
//{
//  F f1(2, 5), f2(4, 9), f3(17, 3);
//  cout << ++f1 << std::endl;//f1.operator++()
//  cout << f2++ << std::endl;//f2.operator++(0)
//  cout << "f1=" << f1 << ", f2= " << f2 << std::endl;
//  cout << --f3 << std::endl;//operator--(f3)
//  cout << f3-- << std::endl;//operator--(f3,0)
//  cout << f3 << std::endl;
//
//  //匿名对象,有点像类型转换,如果只有一个参数,可以看成类型转换(F)3 也是可以的
//  cout << F(3) << endl;
//
//  cout << double(f1) << endl;//f1.operator double()
//  cout <<boolalpha<< bool(f3) << endl;//f1.operator bool()
//
//  //实参初始化形参是可以的F a(6);没有问题
//  func1(6);
//
//  system("pause");
//
//
//}


//TEST4  []
//模仿一个数组
#include <iostream>

using namespace std;

class A {
public:
    typedef unsigned int uint;
private:
    int * p;
    uint n;
public:
    A(uint n) :n(n) { p = new int[n]; if (p == NULL) throw 0; memset(p,0,n*4); }//初始化数组的初始值
    ~A() { delete[] p; }

    //必须加const!!!!!!!!!!!!!!!!!!!!!函数体之前加const,一方面是为了不改变成员变量,另一方面是用于常量成员
    //越界肯定有问题!!!!!!!!!!!!!!!!!
    int& operator[](uint i) const { if (i >= n) throw 1; return p[i]; }//有点像递归,其实不是
    int& operator[](const char* c) const 
    { 
        //atoi: "123"==>123. 不是整数不知道
        int i = atoi(c);
        if (i<0||i>=n) throw 1; return p[i]; 
    }//有点像递归,其实不是

    uint size() const { return n; }

    void operator()(int v) {
        for (int i = 0; i < n; i++) {
            p[i] = v;
        }
    }

    void operator()(const char* s) {
        int v = atoi(s);
        for (int i = 0; i < n; i++) {
            p[i] += v;
        }
    }
    int operator()(int beg, int delta)
    {
        for (int i = 0; i < n; i++)
        {
            p[i] = beg, beg += delta;
        }
        return p[n - 1];
    }

};

ostream& operator<<(ostream& o, const A& a)
{
        o << "{";
        for (int i = 0; i < a.size(); i++) {
            cout << a[i] << " ";
        }
        o << "}";
        return o;
}
int main()
{

    A x(5), y(8);
    x[2] = 20; y[6] = 66;//x.operator[](2)  y.operator[](6)
    cout <<"x= "<<x<<",y= "<<y << endl;
    x["0"] = 8; y["2"] = 33;
    cout << "x= " << x << ",y= " << y << endl;
    cout << x[2];

    x(3);//x.operator()(3)
    cout << x << endl;
    y("50");
    cout << y << endl;
    
    // 10开始,按2递增.
    // 函数对象,很像函数,他可以有很多东西!!!!!
    cout<<"last element : "<<x(10,2);//x.operator()(10,2)
    cout <<"x= "<< x<<endl;
    system("pause");
}


//()  多少目都可以,多目运算符

相关文章

  • [陈宗权C++]C++第4天PM--运算符重载

    参考: 重点: 智能指针模拟,计数器运算符重载 operator-> operator* ++a ,a++,--a...

  • 1.2.15_C++ 关系运算符重载

    C++ 重载运算符和重载函数 C++ 语言支持各种关系运算符( < 、 > 、 <= 、 >= 、 == 等等),...

  • 第十一章 使用类

    运算符重载 运算符重载是一种形式的C++多态。运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。...

  • C++ 重载运算符

    C++重载运算符

  • C++运算符重载

    C++运算符重载的实质:运算符重载的实质就是函数重载或函数多态。运算符重载是一种形式的C++多态。目的在于让人能够...

  • C++ 运算符重载

    运算符重载将重载的概念扩展到运算符上,允许赋予C++运算符多种含义。实际上,很多C++运算符已经重载。将*运算符用...

  • 1.2.17_C++ ++ 和 -- 运算符重载

    C++ 重载运算符和重载函数 递增运算符( ++ )和递减运算符( -- )是 C++ 语言中两个重要的一元运算符...

  • 1.2.20_C++ 下标运算符 [] 重载

    C++ 重载运算符和重载函数 下标操作符 [] 通常用于访问数组元素。重载该运算符用于增强操作 C++ 数组的功能...

  • 1.2.16_C++ 输入/输出运算符重载

    C++ 重载运算符和重载函数 C++ 能够使用流提取运算符 >> 和流插入运算符 << 来输入和输出内置的数据类型...

  • 笔试刷题笔记

    C++中运算符重载是多态性的一种表现 运算符重载是针对C++原有运算符进行的,不可能通过重载创造出新的运算符 除了...

网友评论

      本文标题:[陈宗权C++]C++第4天PM--运算符重载

      本文链接:https://www.haomeiwen.com/subject/tygwthtx.html