锻炼类内声明,类外实现的写法---使用作用域符号::
1)友元--friend--让一个函数或类访问另一个类中私有成员
1)全局函数做友元
在类中用friend声明全局函数是友元即可
2)类做友元
在类中用friend声明类是友元即可
3)类中成员函数做友元
在类中用friend声明类中成员函数是友元即可
2)运算符重载--对已有的运算符重新进行定义,赋予其另一种功能,以适用不同的自定义数据类型---operator运算符
1)加号+运算符重载--实现自定义数据类型相加运算
成员函数--本质:类名 p3 = p1.operator+(p2)
全局函数重载--本质:类名 p3 = operator+(p1,p2)
运算符重载也可以发生函数重载
内置数据类型不能改变运算方式
2)左移<<运算符重载
1)不会利用成员函数来重载<<运算符---因为无法实现cout在左侧
2)只能利用全局函数来重载<<运算符
-----cout输出流(ostream)对象--返回为输出流对象的引用(链式编程)
-----
ostream& operator<< (ostream &cout, Person &p)
{
cout << " m_A = " << p.m_A << "m_B" <<p.m_B;
return cout;
}
3)递增++运算符重载
1)前置++重载
返回引用--可以链式编程
2)后置++重载
返回值
4)赋值=运算符重载
//重载 赋值运算符
Person & operator=(Person &p)
{
//编译器提供的浅拷贝
//m_Age = p.m_Age;
//应先判断是否有属性在堆区,若有先释放干净,然后再深拷贝
//1)释放内存
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
//2)深拷贝---重新申请一块内存空间
m_Age = new int(*p.m_Age);
//返回对象的本身---链式编程思想
return *this;
}
5)关系==运算符重载
//重载 ==
bool operator==(Person& p)
{
if (this->m_Age == p.m_Age && this->m_Name == p.m_Name)
{
return true;
}
return false;
}
6)函数调用运算符重载 ----SPL中用的比较多---就是重载小括号()
//由于使用起来很像函数调用,因此称为仿函数
//仿函数非常灵活,没有固定的写法
class Myprint
{
public:
//重载函数调用运算符
void operator()(string test)
{
cout << test << endl;
}
};
void test3()
{
Myprint myprint;
myprint("hello world");//由于使用起来很像函数调用,因此称为仿函数
}
//回顾匿名函数对象--类型+()==匿名对象(即没有名的对象---当前行执行完之后立马被释放)