接着上一章节继续:第十章丨C++编程宝典:快速上手、深入进阶、挑战高级技巧,助你成为编程达人 – 菜鸟资源 (xiciw.com)
正文讲解开始 今天我们讲解的是运算符重载提高篇
6.5. 运算符重载提高篇
6.5.1. 函数操作符(())—仿函数
把类对象像函数名一样使用。
仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一 个 operator(),这个类就有了类似函数的行为,就是一个仿函数类了。 格式
class 类名
{
返值类型 operator()(参数类型)
函数体
}
应用
#include <iostream>
#include <vector>
using namespace std;
class Sqr
{
public:
int operator()(int i)
{
return i*i;
}
double operator ()(double d)
{
return d*d;
}
};
int main()
{
Sqr sqr;
int i = sqr(4); //sqr.opreator()(4);
double d = sqr(5.5); //sqr.operator()(5.5);
cout<<i<<endl;
cout<<d<<endl;
return 0;
}
注:
主要应用于 STL 和模板,后续会讲。
6.5.2. 堆内存操作符 (new delete)
适用于极个别情况需要定制的时候才用的到。一般很少用。
格式如下:
operator new
operator delete
operator new[]
operator delete[]
全局重载
void * operator new (size_t size)
{
cout<<"new "<<size<<endl;
return malloc(size);
}
void operator delete(void *p)
{
cout<<"delete"<<endl;
free(p);
}
void * operator new[] (size_t size)
{
cout<<"new[] "<<size<<endl;
return malloc(size);
}
void operator delete[](void *p)
{
cout<<"delete[] "<<endl;
free(p);
}
测试:
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A destructor"<<endl;
}
private:
int a;
};
int main()
{
int *p = new int;
delete p;
int *pa = new int[20];
delete []pa;
A * cp = new A;
delete cp;
A * cpa = new A[20];
delete []cpa;
return 0;
}
类中重载
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A destructor"<<endl;
}
void * operator new (size_t size)
{
cout<<"new "<<size<<endl;
return malloc(size);
}
void operator delete(void *p)
{
cout<<"delete"<<endl;
free(p);
}
void * operator new[] (size_t size)
{
cout<<"new[] "<<size<<endl;
return malloc(size);
}
void operator delete[](void *p)
{
cout<<"delete[] "<<endl;
free(p);
}
private:
int a;
};
int main()
{
// int *p = new int;
// delete p;
// int *pa = new int[20];
// delete []pa;
A * cp = new A;
delete cp;
A * cpa = new A[20];
delete []cpa;
return 0;
}
6.5.3. 解引用与智能指针(-> /*)
常规意义上讲,new 或是 malloc 出来的堆上的空间,都需要手动 delete 和 free 的。但在其它高级语言中,只需申请无需释放的功能是存在的。
c++中也提供了这样的机制。我们先来探究一下实现原理。
常规应用
class A
{
public:
A()
{
cout<<"A()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
void func()
{
cout<<"hahaha"<<endl;
}
};
void foo()
{
A*p = new A;
//
delete p;
}
智能指针
#include <memory>
void foo()
{
auto_ptr<A> p (new A);
p->func();
(*p).func();
}
推演
1st step
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A destructor"<<endl;
}
};
class PMA
{
public:
PMA(A *p)
:_p(p){}
~PMA()
{
delete _p;
}
private:
A * _p;
};
int main()
{
A * p = new A;
PMA pma(new A);
return 0;
}
2sd step
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
A()
{
cout<<"A constructor"<<endl;
}
~A()
{
cout<<"A destructor"<<endl;
}
void dis()
{
cout<<"in class A's dis"<<endl;
}
};
class PMA
{
public:
PMA(A *p)
:_p(p){}
~PMA()
{
delete _p;
}
A& operator*()
{
return *_p;
}
A* operator->()
{
return _p;
}
private:
A * _p;
};
int main()
{
A * p = new A;
PMA pma(new A);
// pma._p->dis(); private 的原因破坏了封装
(*pma).dis();
pma->dis();
return 0;
}
->和* 重载格式
类名& operator*()
{
函数体
}
类名* operator->()
{
函数体
}
6.6. 作业
6.6.1. 设计TDate类
定义一个处理日期的类 TDate,它有 3 个私有数据成员:Month,Day,Year 和若干个公有成员函数,并实现如下要求:
①构造函数重载
②成员函数设置缺省参数
③可使用不同的构造函数来创建不同的对象
④定义一个友元函数来打印日期
6.6.2. 设计一个矩阵类
设计一个 3*3 的矩阵类 class Matrix,通过一数组进行初始化。要求如下:
①默认构造(初始化为 0),有参构造(数组作实参)
②重载+ / +=
③重载* / *=
④实现输出
提示:
class Matrix
{
public:
Matrix(void);
Matrix(int p[][3]);
private:
int data[3][3];
};
本章完,下一章我们讲解:继承与派生(Inherit&&Derive)