目录
一、常对象和常函数
1、用const修饰成员函数,const修饰this指针指向的内存区域,成员函数体内不能修改本类中的任何普通成员变量;
2、当成员变量类型前面被mutable修饰时是可以被const修饰的成员函数所修改的。
class Person{
public:
int m_Age;
mutable int m_Height;
Person(int age)
{
this->m_Age = age;
}
void show() const //常函数
{
this->m_Height = 100;
cout<< this->m_Age <<endl;
}
void show1(){}
};
int main()
{
Person p1(20);
p1.show();
const Person p2(30); //常对象
p2.m_Height = 290;//常对象可以修改mutable修饰的成员变量
p2.show();//常对象可以调用常函数
//p2.show1(),常对象不能调用普通函数
return 0;
}
二、友元
友元的作用:在类外访问一个类的私有成员。
友元有三种
1、友元(全局)函数
2、友元类
3、友元成员函数
注意事项:
1、友元关系不能被继承;
2、友元关系是单向的,类A是类B的好朋友,但类B不是类A的好朋友;
3、友元关系不具有传递性,类B是类A的好朋友,类C是类B的好朋友,但类A不是类C的好朋友。
class Buliding{
//让全局函数visit作为本类的Building的好朋友,就可以访问私有成员
friend void visit(Building &building);
public:
string m_SittingRoom;//客厅
Building()
{
m_SittingRoom = "客厅";
m_BedRoom = "卧室";
}
private:
string m_BedRoom; //卧室
};
void visit(Building& building)//全局函数
{
cout<<"正在访问:"<<building.m_SittingRoom<<endl;
//因为visit已经和building是好朋友了,所以可以访问它的私有成员
cout<<"正在访问:"<<building.m_BedRoom<<endl;
}
int main()
{
//创建一个Building对象
Building building;
visit(building);
return 0;
}
三、运算符重载
运算符重载是带有特殊名称的函数,函数名是由关键字operator和其后要重载的运算符符号构成。与其他函数一样,重载运算符有一个返回类型和参数列表。
#include <iostream>
using namespace std;
class Complex
{
public:
double real, imag;
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) { }
Complex operator - (const Complex & c);
};
Complex operator + (const Complex & a, const Complex & b)
{
return Complex(a.real + b.real, a.imag + b.imag);
}
Complex Complex::operator - (const Complex & c)
{
//返回一个临时对象,切记,一定要加Complex,否则会报错
return Complex(real - c.real, imag - c.imag); //返回一个临时对象
}
int main()
{
Complex a(4, 4), b(1, 1), c;
c = a + b; //等价于 c = operator + (a,b);
cout << c.real << "," << c.imag << endl;
cout << (a - b).real << "," << (a - b).imag << endl; //a-b等价于a.operator - (b)
return 0;
}
1、指针运算符重载
智能指针:智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。
#include <iostream>
using namespace std;
class Person{
public:
int m_Age;
Person(int age){
cout<<"Person的构造函数"<<endl;
m_Age = age;
}
//输出信息
void showAge(){
cout<<"m_Age="<<this->m_Age<<endl;
}
~Person(){
cout<<"Person的析构函数"<<endl;
}
};
//智能指针类:
class SmartPoint{
public:
Person* m_Person;
Person* operator->(){ //指向她的成员,意思是要返回她的成员
return this->m_Person;
}
Person& operator*(){ //指向她的地址,返回她的解引用
return *m_Person;
}
SmartPoint(Person* p)
{
m_Person = p;
}
~SmartPoint()
{
cout<<"SmartPoint析构函数"<<endl;
if(this->m_Person != NULL)
{
delete this->m_Person;
this->m_Person = NULL;
}
}
};
int main()
{
//创建Person的对象
Person* P=new Person(30);//在堆上开辟了一个值为30的指针变量,把指针地址保存到栈上
P->showAge();
(*P).showAge();//跟上面的表达意思是一样的
//delete P;
cout<<"**************"<<endl;
SmartPoint sp(P);//拷贝构造函数
sp->showAge(); //sp.operator->();
(*sp).showAge();//跟上面的这行表达意思是一样的
return 0;
}
2、函数调用运算符重载
#include <iostream>
using namespace stdl;
class MyPrint{
public:
//重载()运算符
void operator()(string text)
{
cout<<text<<endl;
}
};
class MyAdd{
public:
//仿函数非常灵活,没有固定的写法
int operator()(int a,int b)
{
return a+b;
}
};
int getSum(int a,int b)
{
return a+b;
}
int main()
{
MyPrint mp;
mp("hello world!");
MyAdd add;
int sum=add(10,20);
cout<<"sum="<<sum<<endl;
int sum2=getSum(10,20);
cout<<"sum2="<<sum2<<endl;
return 0;
}
总结:只要我们勤加练习,一定能把它掌握住,运算符重载这块特别费心费神!