C核心编程(三)1 类和对象1.1 C对象模型和this指针1.1.1 成员变量和成员函数分开存储在C中类内的成员变量和成员函数分开存储只有非静态成员变量才属于类的对象上#include iostream using namespace std; //成员变量和成员函数是分开存储的 class Person { public: int m_A;//非静态成员变量 属于类的对象上 static int m_B;//静态成员变量 不属于类的对象上 void func() {//非静态成员函数 不属于类对象上 } static void func2() {//静态成员函数 不属于类的对象上 } }; int Person::m_B0; void test01() { Person p; //空对象占用的内存空间为1 //C编译器会给每个空对象也分配一个字节空间是为了区分空对象占内存的位置 //每个空对象也应该有一个独一无二的内存地址 cout size of p sizeof(p) endl; } void test02() { Person p; cout size of p sizeof(p) endl; //计算的是类的对象占用的内存大小除了非静态变量其他内存大小都不变 //说明其他都不在类的对象上 } int main() { // test01();//1 test02();//4 system(pause); return 0; }1.1.2 this指针概念this指针指向被调用的成员函数所属的对象this指针是隐含每一个非静态成员函数内的一种指针this指针不需要定义直接使用即可this指针的用途当形参和成员变量同名时可用this指针来区分在类的非静态成员函数中返回对象本身可使用return*this#include iostream using namespace std; class Person { public: Person(int age) {//形参 //this指针指向的是被调用的成员函数所属的对象 this-age age;//this指向p1 } Person PersonAddAge(Person p) {//Person就是直接把p2这个对象本身返回回去而不是复制一份新的 //如果把删掉函数就变成了值传递返回的对象不是原来的对象而是复制一份新的对象 //只有第一次是p2后面是复制品题干要求输出p2只会输出20 this-age p.age; //this是指向p2的指针而*this指向的就是p2这个对象本体 return *this; } int age;//成员属性要跟形参区分 }; //1、解决名称冲突 void test01() { Person p1(18); cout p1的年龄 p1.age endl; } //2、返回对象本身用*this void test02() { Person p1(10); Person p2(10); //链式编程思想 p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);//p2p2p1p1 cout p2的年龄为 p2.age endl;//40 } int main() { //test01();//18 test02(); system(pause); return 0; }1.1.3 空指针访问程序函数C空指针也可以调用成员函数但是也要注意有没有用到this指针如果用到this指针需要加以判断保证代码的健壮性#include iostream using namespace std; //空指针调用成员函数 class Person { public: void showClassName() { cout this is Person class endl; } void showPersonAge() { //报错的原因是因为传入的指针是为NULL if (this NULL) { return;//代码到这一行结束不会运行下面的这样代码不会崩溃 } cout age this-m_Age endl; } int m_Age; }; void test01() { Person* pNULL; //p-age等价于(*p).age通过指针来访问对象中的成员对象用.指针用- p-showClassName();//输出this is Person class p-showPersonAge();//不输出 } int main() { test01(); system(pause); return 0; }1.1.4 const修饰成员函数常函数成员函数后加const后我们称为这个函数为常函数常函数内不可以修改成员属性成员属性声明时加关键字mutablie后在常函数中依然可以修改常对象声明对象前加const称该对象为常对象常对象只能调用常函数#include iostream using namespace std; //常函数 class Person { public: //this指针的本质指针常量 指针的指向是不可以修改的 //const Person *const this; //在成员函数后面加const修饰的是this指向让指针指向的值也不可以修改 void showPerson()const { this-m_B100; //this-m_A100; //thisNULL;//this指针不可以修改指针的指向 } void func() { } int m_A; mutable int m_B;//特殊变量即使在常函数中也可以修改这个值加关键字mutable }; void test01() { Person p; p.showPerson(); } //常对象 void test02() { const Person p;//在对象前加const变为常对象 //p.m_A 100; p.m_B 100;//m_B是特殊值在常对象下也可以修改 //常对象只能调用常函数 p.showPerson(); //p.func();//常对象不可以调用普通成员函数因为普通成员函数可以修改属性 } int main() { system(pause); return 0; }1.2 友元友元目的就是为了声明一些特殊的函数或者特殊的类访问另一个类中私有成员友元的关键字friend友元的三种实现全局函数做友元类做友元成员函数做友元示例1全局函数做友元#include iostream #includestring using namespace std; //建筑物类 class Building { //goodGay全局函数是Building的好朋友可以访问Building中私有成员 friend void gooodGay(Building* building); public: Building() { m_SittingRoom 客厅; m_BedRoom 卧室; } string m_SittingRoom;//客厅 private: string m_BedRoom;//卧室 }; //全局函数作用是访问并打印Building对象的成员输出对象信息 void gooodGay(Building *building) { cout 好基友的全局函数正在访问building-m_SittingRoom endl; cout 好基友的全局函数正在访问building-m_BedRoom endl; } //测试函数用来验证goodGay能否正常工作创建Build对象并调用goodGay void test01() { Building building; gooodGay(building); } int main() { test01(); system(pause); return 0; }示例2类做友元#include iostream #includestring using namespace std; //类做友元 class Building; //GoodGay类 class GoodGay { public: GoodGay();//类内进行构造函数的声明类外才是它的实现赋值 void visit();//参观函数访问Building中的属性 Building *building;//声明一个指针变量用指针占一个位置暂时引用还没完整定义的Building类 }; //Building类 class Building { //GoodGay类是本类的好朋友可以访问本类中私有成员 friend class GoodGay; public: Building();//定义的构造函数声明为了给这两个成员变量初始化赋值 public: string m_SittingRoom;//客厅 private: string m_BedRoom;//卧室 }; //类外写成员函数 Building::Building() { m_SittingRoom 客厅; m_BedRoom 卧室; } GoodGay::GoodGay() { //创建建筑物对象 building new Building;//用new Building创建对象把对象地址赋给Building * building就有指向了 } void GoodGay::visit() { cout 好基友类正在访问 building-m_SittingRoom endl; cout 好基友类正在访问 building-m_BedRoom endl; } void test01() { GoodGay g; g.visit(); } int main() { test01(); system(pause); return 0; }示例3成员函数做友元#include iostream #include string using namespace std; class Building; class GoodGay { public: GoodGay(); void visit1();//让visit函数可以访问Building中私有成员 void visit2();//让visit2函数不可以访问Building中私有成员 Building *building; }; class Building { //告诉编译器 GoodGay类下的visit成员函数作为本类的好朋友可以访问私有成员 friend void GoodGay::visit1(); public: Building(); public: string m_SittingRoom;//客厅 private: string m_BedRoom;//卧室 }; //类外实现成员函数 Building::Building() { m_SittingRoom 客厅; m_BedRoom 卧室; } GoodGay::GoodGay() { building new Building; } void GoodGay:: visit1() { cout visit1函数正在访问 building-m_SittingRoom endl; cout visit1函数正在访问 building-m_BedRoom endl; } void GoodGay::visit2() { cout visit2函数正在访问 building-m_SittingRoom endl; //cout visit2函数正在访问 building-m_BedRoom endl; } void visit2() { } void test01() { GoodGay g; g.visit1(); g.visit2(); } int main() { test01(); system(pause); return 0; }1.3 运算符重载概念对已有的运算符重新进行定义赋予其另一种功能以适应不同的数据类型1.3.1 加号运算符重载作用实现两个自定义数据类型相加的运算分析#include iostream using namespace std; //加号运算符重载 class Person { public: //1、通过成员函数重载号 //Person operator(Person p) { // Person temp; // temp.m_A this-m_A p.m_A; // temp.m_B this-m_B p.m_B; // return temp; //} int m_A; int m_B; }; //2、通过全局函数重载号 Person operator(Person p1,Person p2) { Person temp; temp.m_A p1.m_A p2.m_A; temp.m_B p1.m_B p2.m_B; return temp; } //函数重载的版本 Person operator (Person p1,int num) { Person temp; temp.m_A p1.m_A num; temp.m_B p1.m_B num; return temp; } void test01() { Person p1; p1.m_A 10; p1.m_B 10; Person p2; p2.m_A 10; p2.m_B 10; //成员函数重载本质调用 //Person p3 p1.operator(p2); //全局函数重载本质调用 //Person p3operate(p1p2); Person p3 p1 p2; //运算符重载也可以发生函数重载 Person p4 p1 100;//Personint cout p3.m_A p3.m_A endl; cout p3.m_B p3.m_B endl; cout p4.m_B p4.m_B endl; cout p4.m_A p4.m_A endl; } int main() { test01(); system(pause); return 0; }输出结果为1.3.2 左移运算符重载作用可以输出自定义数据类型#include iostream using namespace std; //左移运算符重载 class Person { friend ostream operator(ostream cout, Person p); public: Person(int a,int b) { m_A a; m_B b; } private: //利用成员函数重载 左移运算符 p.operatorcout 简化版本 pcout //不会利用成员函数重载运算符因为无法实现cout在左侧 //void operator(cout) { //} int m_A; int m_B; }; //只能利用全局函数重载左移运算符 ostream operator(ostreamcout, Personp) {//本质 operator(cout,p) 简化coutp cout m_A p.m_A m_B p.m_B endl; return cout; } void test01() { Person p(10,10); //p.m_A 10; //p.m_B 10; cout p; cout plove endl; } int main() { test01(); system(pause); return 0; }输出结果为1.3.3 递增运算符重载作用作为重载递增运算符实现自己的整型数据分析#include iostream using namespace std; //重载递增运算符 //自定义整型 class MyInteger { friend ostream operator(ostreamcout, MyInteger myint); public: MyInteger() { m_Num 0; } //重载前置运算符 返回引用是为了一直对一个数据进行递增操作 MyInteger operator() { //先进行运算 m_Num; //再将自身做返回 return *this; } //重载后置运算符 //void operator(int) int 代表占位参数可以用于区分前置和后置递增 MyInteger operator(int) { //先记录当时结果 MyInteger temp *this; //后递增 m_Num; //最后将记录结果做返回 return temp; } private : int m_Num; }; // 重载运算符 ostream operator(ostreamcout,MyInteger myint) { cout myint.m_Num endl; return cout; } void test01() { MyInteger myint; cout myint endl; } void test02() { MyInteger myint; cout myint endl; } int main() { //test01(); test02(); system(pause); return 0; }1.3.4 赋值运算符重载C编译器至少给一个类添加4个函数默认构造函数(无参函数体为空)默认析构函数(无参函数体为空)默认拷贝构造函数对属性进行值拷贝赋值运算符operator对属性进行值拷贝分析#include iostream using namespace std; //赋值运算符重载 class Person { public: Person(int age) { m_Age new int(age);//在堆区创建一个存年龄的空间 让m_Age记住这个地址 } ~Person(){ if (m_Age ! NULL) { delete m_Age; m_Age NULL; } } //重载 赋值运算符 Person operator(Person p) { //编译器是提供浅拷贝 //m_Age p.m_Age; //应该先判断是否有属性在堆区如果有先释放干净然后再深拷贝 if (m_Age ! NULL) { delete m_Age; } //深拷贝 m_Age new int(*p.m_Age); //返回对象的本身 return*this;//返回自身接着操作,返回的是赋值后的p2 } int* m_Age;//将指针开辟到堆区本来是存放一个数值现在相当于存放这个数值的地址 }; void test01() { Person p1(18); Person p2(20); Person p3(30); p3 p2 p1;//赋值操作 cout p1的年龄为 * p1.m_Age endl;//18 cout p2的年龄为 * p2.m_Age endl;//18 cout p3的年龄为 * p3.m_Age endl;//18 } int main() { test01(); //int a 10; //int b 10; //int c 10; //cout a a endl;//10 //cout b b endl;//10 //cout c c endl;//10 system(pause); return 0; }1.3.5 关系运算符重载作用重载关系运算符可以让两个自定义类型对象进行对比操作#include iostream #includestring using namespace std; //重载关系运算符 ! class Person { public : Person(string name, int age) { m_Name name; m_Age age; } //重载号 bool operator(Person p) { if (this-m_Name p.m_Name this-m_Age p.m_Age) { return true; } else { return false; } } bool operator!(Person p) { if (this-m_Name p.m_Name this-m_Age p.m_Age) { return false; } else { return true; } } string m_Name; int m_Age; }; void test01() { Person p1(Tom, 18); Person p2(T, 18); if (p1 p2) { cout p1和p2是相等的 endl; } else { cout p1和p2是不相等的 endl; } if (p1 ! p2) { cout p1和p2是不相等的 endl; } else { cout p1和p2是相等的 endl; } } int main() { test01(); system(pause); return 0; }1.5.6 函数调用运算符重载函数调用运算符()也可以重载由于重载后使用的方式非常像函数的调用因此称为仿函数仿函数没有固定写法非常灵活#include iostream #includestring using namespace std; //函数调用运算符重载 //打印输出类 class MyPrint { public: //重载函数调用运算符 void operator()(string test) { cout test endl; } }; void MyPrint02(string test) {//正常的函数 cout test endl; } void test01() { MyPrint myPrint; myPrint(hello);//由于使用起来非常像函数调用因此称为仿函数 MyPrint02(oooooo);//函数调用 } //仿函数非常灵活没有固定写法 //加法类 class MyAdd { public: int operator()(int num1,int num2) { return num1 num2; } }; void test02() { MyAdd myadd; int ret myadd(88, 66); cout ret ret endl;//154 //匿名函数对象 cout MyAdd()(100, 100) endl; } int main() { //test01(); test02(); system(pause); return 0; }知识点回顾int *pnew int(10);//在堆上开辟一个内存空间里面存的值是10把地址交给指针pp-age等价于(*p).age通过指针来访问对象中的成员对象用.指针用-
C++核心编程--this指针、友元、运算符重载详解
C核心编程(三)1 类和对象1.1 C对象模型和this指针1.1.1 成员变量和成员函数分开存储在C中类内的成员变量和成员函数分开存储只有非静态成员变量才属于类的对象上#include iostream using namespace std; //成员变量和成员函数是分开存储的 class Person { public: int m_A;//非静态成员变量 属于类的对象上 static int m_B;//静态成员变量 不属于类的对象上 void func() {//非静态成员函数 不属于类对象上 } static void func2() {//静态成员函数 不属于类的对象上 } }; int Person::m_B0; void test01() { Person p; //空对象占用的内存空间为1 //C编译器会给每个空对象也分配一个字节空间是为了区分空对象占内存的位置 //每个空对象也应该有一个独一无二的内存地址 cout size of p sizeof(p) endl; } void test02() { Person p; cout size of p sizeof(p) endl; //计算的是类的对象占用的内存大小除了非静态变量其他内存大小都不变 //说明其他都不在类的对象上 } int main() { // test01();//1 test02();//4 system(pause); return 0; }1.1.2 this指针概念this指针指向被调用的成员函数所属的对象this指针是隐含每一个非静态成员函数内的一种指针this指针不需要定义直接使用即可this指针的用途当形参和成员变量同名时可用this指针来区分在类的非静态成员函数中返回对象本身可使用return*this#include iostream using namespace std; class Person { public: Person(int age) {//形参 //this指针指向的是被调用的成员函数所属的对象 this-age age;//this指向p1 } Person PersonAddAge(Person p) {//Person就是直接把p2这个对象本身返回回去而不是复制一份新的 //如果把删掉函数就变成了值传递返回的对象不是原来的对象而是复制一份新的对象 //只有第一次是p2后面是复制品题干要求输出p2只会输出20 this-age p.age; //this是指向p2的指针而*this指向的就是p2这个对象本体 return *this; } int age;//成员属性要跟形参区分 }; //1、解决名称冲突 void test01() { Person p1(18); cout p1的年龄 p1.age endl; } //2、返回对象本身用*this void test02() { Person p1(10); Person p2(10); //链式编程思想 p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);//p2p2p1p1 cout p2的年龄为 p2.age endl;//40 } int main() { //test01();//18 test02(); system(pause); return 0; }1.1.3 空指针访问程序函数C空指针也可以调用成员函数但是也要注意有没有用到this指针如果用到this指针需要加以判断保证代码的健壮性#include iostream using namespace std; //空指针调用成员函数 class Person { public: void showClassName() { cout this is Person class endl; } void showPersonAge() { //报错的原因是因为传入的指针是为NULL if (this NULL) { return;//代码到这一行结束不会运行下面的这样代码不会崩溃 } cout age this-m_Age endl; } int m_Age; }; void test01() { Person* pNULL; //p-age等价于(*p).age通过指针来访问对象中的成员对象用.指针用- p-showClassName();//输出this is Person class p-showPersonAge();//不输出 } int main() { test01(); system(pause); return 0; }1.1.4 const修饰成员函数常函数成员函数后加const后我们称为这个函数为常函数常函数内不可以修改成员属性成员属性声明时加关键字mutablie后在常函数中依然可以修改常对象声明对象前加const称该对象为常对象常对象只能调用常函数#include iostream using namespace std; //常函数 class Person { public: //this指针的本质指针常量 指针的指向是不可以修改的 //const Person *const this; //在成员函数后面加const修饰的是this指向让指针指向的值也不可以修改 void showPerson()const { this-m_B100; //this-m_A100; //thisNULL;//this指针不可以修改指针的指向 } void func() { } int m_A; mutable int m_B;//特殊变量即使在常函数中也可以修改这个值加关键字mutable }; void test01() { Person p; p.showPerson(); } //常对象 void test02() { const Person p;//在对象前加const变为常对象 //p.m_A 100; p.m_B 100;//m_B是特殊值在常对象下也可以修改 //常对象只能调用常函数 p.showPerson(); //p.func();//常对象不可以调用普通成员函数因为普通成员函数可以修改属性 } int main() { system(pause); return 0; }1.2 友元友元目的就是为了声明一些特殊的函数或者特殊的类访问另一个类中私有成员友元的关键字friend友元的三种实现全局函数做友元类做友元成员函数做友元示例1全局函数做友元#include iostream #includestring using namespace std; //建筑物类 class Building { //goodGay全局函数是Building的好朋友可以访问Building中私有成员 friend void gooodGay(Building* building); public: Building() { m_SittingRoom 客厅; m_BedRoom 卧室; } string m_SittingRoom;//客厅 private: string m_BedRoom;//卧室 }; //全局函数作用是访问并打印Building对象的成员输出对象信息 void gooodGay(Building *building) { cout 好基友的全局函数正在访问building-m_SittingRoom endl; cout 好基友的全局函数正在访问building-m_BedRoom endl; } //测试函数用来验证goodGay能否正常工作创建Build对象并调用goodGay void test01() { Building building; gooodGay(building); } int main() { test01(); system(pause); return 0; }示例2类做友元#include iostream #includestring using namespace std; //类做友元 class Building; //GoodGay类 class GoodGay { public: GoodGay();//类内进行构造函数的声明类外才是它的实现赋值 void visit();//参观函数访问Building中的属性 Building *building;//声明一个指针变量用指针占一个位置暂时引用还没完整定义的Building类 }; //Building类 class Building { //GoodGay类是本类的好朋友可以访问本类中私有成员 friend class GoodGay; public: Building();//定义的构造函数声明为了给这两个成员变量初始化赋值 public: string m_SittingRoom;//客厅 private: string m_BedRoom;//卧室 }; //类外写成员函数 Building::Building() { m_SittingRoom 客厅; m_BedRoom 卧室; } GoodGay::GoodGay() { //创建建筑物对象 building new Building;//用new Building创建对象把对象地址赋给Building * building就有指向了 } void GoodGay::visit() { cout 好基友类正在访问 building-m_SittingRoom endl; cout 好基友类正在访问 building-m_BedRoom endl; } void test01() { GoodGay g; g.visit(); } int main() { test01(); system(pause); return 0; }示例3成员函数做友元#include iostream #include string using namespace std; class Building; class GoodGay { public: GoodGay(); void visit1();//让visit函数可以访问Building中私有成员 void visit2();//让visit2函数不可以访问Building中私有成员 Building *building; }; class Building { //告诉编译器 GoodGay类下的visit成员函数作为本类的好朋友可以访问私有成员 friend void GoodGay::visit1(); public: Building(); public: string m_SittingRoom;//客厅 private: string m_BedRoom;//卧室 }; //类外实现成员函数 Building::Building() { m_SittingRoom 客厅; m_BedRoom 卧室; } GoodGay::GoodGay() { building new Building; } void GoodGay:: visit1() { cout visit1函数正在访问 building-m_SittingRoom endl; cout visit1函数正在访问 building-m_BedRoom endl; } void GoodGay::visit2() { cout visit2函数正在访问 building-m_SittingRoom endl; //cout visit2函数正在访问 building-m_BedRoom endl; } void visit2() { } void test01() { GoodGay g; g.visit1(); g.visit2(); } int main() { test01(); system(pause); return 0; }1.3 运算符重载概念对已有的运算符重新进行定义赋予其另一种功能以适应不同的数据类型1.3.1 加号运算符重载作用实现两个自定义数据类型相加的运算分析#include iostream using namespace std; //加号运算符重载 class Person { public: //1、通过成员函数重载号 //Person operator(Person p) { // Person temp; // temp.m_A this-m_A p.m_A; // temp.m_B this-m_B p.m_B; // return temp; //} int m_A; int m_B; }; //2、通过全局函数重载号 Person operator(Person p1,Person p2) { Person temp; temp.m_A p1.m_A p2.m_A; temp.m_B p1.m_B p2.m_B; return temp; } //函数重载的版本 Person operator (Person p1,int num) { Person temp; temp.m_A p1.m_A num; temp.m_B p1.m_B num; return temp; } void test01() { Person p1; p1.m_A 10; p1.m_B 10; Person p2; p2.m_A 10; p2.m_B 10; //成员函数重载本质调用 //Person p3 p1.operator(p2); //全局函数重载本质调用 //Person p3operate(p1p2); Person p3 p1 p2; //运算符重载也可以发生函数重载 Person p4 p1 100;//Personint cout p3.m_A p3.m_A endl; cout p3.m_B p3.m_B endl; cout p4.m_B p4.m_B endl; cout p4.m_A p4.m_A endl; } int main() { test01(); system(pause); return 0; }输出结果为1.3.2 左移运算符重载作用可以输出自定义数据类型#include iostream using namespace std; //左移运算符重载 class Person { friend ostream operator(ostream cout, Person p); public: Person(int a,int b) { m_A a; m_B b; } private: //利用成员函数重载 左移运算符 p.operatorcout 简化版本 pcout //不会利用成员函数重载运算符因为无法实现cout在左侧 //void operator(cout) { //} int m_A; int m_B; }; //只能利用全局函数重载左移运算符 ostream operator(ostreamcout, Personp) {//本质 operator(cout,p) 简化coutp cout m_A p.m_A m_B p.m_B endl; return cout; } void test01() { Person p(10,10); //p.m_A 10; //p.m_B 10; cout p; cout plove endl; } int main() { test01(); system(pause); return 0; }输出结果为1.3.3 递增运算符重载作用作为重载递增运算符实现自己的整型数据分析#include iostream using namespace std; //重载递增运算符 //自定义整型 class MyInteger { friend ostream operator(ostreamcout, MyInteger myint); public: MyInteger() { m_Num 0; } //重载前置运算符 返回引用是为了一直对一个数据进行递增操作 MyInteger operator() { //先进行运算 m_Num; //再将自身做返回 return *this; } //重载后置运算符 //void operator(int) int 代表占位参数可以用于区分前置和后置递增 MyInteger operator(int) { //先记录当时结果 MyInteger temp *this; //后递增 m_Num; //最后将记录结果做返回 return temp; } private : int m_Num; }; // 重载运算符 ostream operator(ostreamcout,MyInteger myint) { cout myint.m_Num endl; return cout; } void test01() { MyInteger myint; cout myint endl; } void test02() { MyInteger myint; cout myint endl; } int main() { //test01(); test02(); system(pause); return 0; }1.3.4 赋值运算符重载C编译器至少给一个类添加4个函数默认构造函数(无参函数体为空)默认析构函数(无参函数体为空)默认拷贝构造函数对属性进行值拷贝赋值运算符operator对属性进行值拷贝分析#include iostream using namespace std; //赋值运算符重载 class Person { public: Person(int age) { m_Age new int(age);//在堆区创建一个存年龄的空间 让m_Age记住这个地址 } ~Person(){ if (m_Age ! NULL) { delete m_Age; m_Age NULL; } } //重载 赋值运算符 Person operator(Person p) { //编译器是提供浅拷贝 //m_Age p.m_Age; //应该先判断是否有属性在堆区如果有先释放干净然后再深拷贝 if (m_Age ! NULL) { delete m_Age; } //深拷贝 m_Age new int(*p.m_Age); //返回对象的本身 return*this;//返回自身接着操作,返回的是赋值后的p2 } int* m_Age;//将指针开辟到堆区本来是存放一个数值现在相当于存放这个数值的地址 }; void test01() { Person p1(18); Person p2(20); Person p3(30); p3 p2 p1;//赋值操作 cout p1的年龄为 * p1.m_Age endl;//18 cout p2的年龄为 * p2.m_Age endl;//18 cout p3的年龄为 * p3.m_Age endl;//18 } int main() { test01(); //int a 10; //int b 10; //int c 10; //cout a a endl;//10 //cout b b endl;//10 //cout c c endl;//10 system(pause); return 0; }1.3.5 关系运算符重载作用重载关系运算符可以让两个自定义类型对象进行对比操作#include iostream #includestring using namespace std; //重载关系运算符 ! class Person { public : Person(string name, int age) { m_Name name; m_Age age; } //重载号 bool operator(Person p) { if (this-m_Name p.m_Name this-m_Age p.m_Age) { return true; } else { return false; } } bool operator!(Person p) { if (this-m_Name p.m_Name this-m_Age p.m_Age) { return false; } else { return true; } } string m_Name; int m_Age; }; void test01() { Person p1(Tom, 18); Person p2(T, 18); if (p1 p2) { cout p1和p2是相等的 endl; } else { cout p1和p2是不相等的 endl; } if (p1 ! p2) { cout p1和p2是不相等的 endl; } else { cout p1和p2是相等的 endl; } } int main() { test01(); system(pause); return 0; }1.5.6 函数调用运算符重载函数调用运算符()也可以重载由于重载后使用的方式非常像函数的调用因此称为仿函数仿函数没有固定写法非常灵活#include iostream #includestring using namespace std; //函数调用运算符重载 //打印输出类 class MyPrint { public: //重载函数调用运算符 void operator()(string test) { cout test endl; } }; void MyPrint02(string test) {//正常的函数 cout test endl; } void test01() { MyPrint myPrint; myPrint(hello);//由于使用起来非常像函数调用因此称为仿函数 MyPrint02(oooooo);//函数调用 } //仿函数非常灵活没有固定写法 //加法类 class MyAdd { public: int operator()(int num1,int num2) { return num1 num2; } }; void test02() { MyAdd myadd; int ret myadd(88, 66); cout ret ret endl;//154 //匿名函数对象 cout MyAdd()(100, 100) endl; } int main() { //test01(); test02(); system(pause); return 0; }知识点回顾int *pnew int(10);//在堆上开辟一个内存空间里面存的值是10把地址交给指针pp-age等价于(*p).age通过指针来访问对象中的成员对象用.指针用-