友元
1.全局函数做友元
#include <iostream>
using namespace std;
/**
* 全局函数做友元
*/
class Building {
friend void coming(Building *building);
public:
string sittingRoom;
Building() {
this->sittingRoom = "客厅";
livingRoom = "卧室"; // 省略this->
}
private:
string livingRoom;
};
// Building中并未声明coming()函数,故此为类外全局函数。
void coming(Building *building) {
cout << "同性正在访问" << building->sittingRoom << endl;
// 如果不用friend声明友元函数则无法访问私有成员变量
cout << "同性正在访问" << building->livingRoom << endl; // friend
}
void test01() {
Building building;
coming(&building);
}
int main() {
test01();
return 0;
}
2.友元类>友元函数,功能相同,需权限处登记
#include <iostream>
using namespace std;
class Building; // 必须声明
class Gay {
// 谁是谁的朋友,友元类到底声明在哪里?-反正不是这里,你需要去权限掌控者处登记。
public:
Gay();
void visit();
void visit2();
private:
Building *building; // 开局不声明,这里则报错
};
class Building {
// 必须在我Building这里登记
// friend class Gay; // 正确,友元类
friend void Gay::visit(); // 这里切记必须Gay的成员函数先声明!!Building和Gay调换位置则失效!!
public:
string sittingRoom;
Building();
private:
string livingRoom;
};
Gay::Gay() {
building = new Building; // 这里的小building在类外居然可以访问,牛逼🐂。
}
void Gay::visit() {
cout << "Gay正在访问" << building->sittingRoom << endl;
cout << "Gay正在访问" << building->livingRoom << endl;
}
// 类外Building的构造函数
Building::Building() {
this->sittingRoom = "客厅";
this->livingRoom = "卧室";
}
void Gay::visit2() {
cout << "Gay正在访问" << building->sittingRoom << endl;
// cout << "Gay正在访问" << building->livingRoom << endl; // visit2()无权限访问livingRoom
}
void test1() {
Gay gay;
gay.visit();
gay.visit2();
}
int main() {
test1();
return 0;
}
运算符重载(全局/成员运算符重载)
1.加号运算符重载
p1+p2,等同于Person p3 = p1.operator+(p2);
2.左移运算符重载(结合全局函数友元)
#include <iostream>
using namespace std;
class Liweitong {
// 在此处注册登记
friend ostream &operator<<(ostream &cout, Liweitong &liweitong);
public:
Liweitong();
private:
string name;
int age;
};
// 全局构造函数
Liweitong::Liweitong() {
name = "weton";
age = 23;
}
// 全局左移运算符重载函数
ostream &operator<<(ostream &cout, Liweitong &liweitong) {
// 这里的name和age为私有属性,若想在全局函数中访问,使用友元
cout << "name=" << liweitong.name << " age=" << liweitong.age << endl;
return cout;
}
void test1() {
Liweitong liweitong;
cout << liweitong << endl;
}
int main() {
test1();
return 0;
}
3.递增运算符重载
// 递增运算符重载
class MyInt {
friend ostream &operator<<(ostream &out, MyInt myInt);
public:
MyInt() {
num = 0;
}
// 前置++
MyInt &operator++() {
num++;
return *this;
}
// 后置++
MyInt operator++(int) {
MyInt myIntTemp = *this;
num++;
return myIntTemp;
}
private:
int num;
};
ostream &operator<<(ostream &out, MyInt myInt) {
out << "num=" << myInt.num;
return out;
}
void test1() {
Liweitong liweitong;
cout << liweitong << endl;
}
void test2() {
MyInt myInt;
cout << ++myInt << endl;
cout << myInt << endl;
}
void test3() {
MyInt myInt;
cout << myInt++ << endl;
cout << myInt << endl;
}
int main() {
test1(); // 全局左移运算符重载 =tostring()
printf("-------------------\n");
test2(); // 前置++
printf("-------------------\n");
test3(); // 后置++
return 0;
}
4.赋值运算符重载
class Li {
public:
Li(int tmpAge) {
age = new int(tmpAge);
}
~Li() { // 此时报错error for object 0x7fe26b704080: pointer being freed was not allocated
if (age !=NULL){
delete age;
age = NULL;
}
}
// 使用赋值运算符重载解决报错问题
Li& operator=(Li &li){
if (age!=NULL){
delete age;
age = NULL;
}
age = new int(*li.age);
return *this;
}
int *age; // int指针类型
};
void test1() {
Liweitong liweitong;
cout << liweitong << endl;
}
void test2() {
MyInt myInt;
cout << ++myInt << endl;
cout << myInt << endl;
}
void test3() {
MyInt myInt;
cout << myInt++ << endl;
cout << myInt << endl;
}
void test4() {
Li l1(10);
Li l2(20);
Li l3(30);
l3 = l2 = l1;
cout << *l1.age << endl; //10
cout << *l2.age << endl; //10
cout << *l3.age << endl; //10
}
5.关系运算符重载
class Guanxi {
public:
string name;
int age;
Guanxi(string name, int age) {
this->name = name;
this->age = age;
}
bool operator==(Guanxi &guanxi) {
if (this->name == guanxi.name && this->age == guanxi.age) {
return true;
}
return false;
}
};
6.函数调用运算符重载
仿函数
//函数调用运算符重载
class MyPrint {
public:
void operator()(string text) {
cout << text << endl;
}
};
class MyAdd{
public:
int operator()(int n1,int n2){
return n1+n2 ;
}
};
void test1() {
Liweitong liweitong;
cout << liweitong << endl;
}
void test2() {
MyInt myInt;
cout << ++myInt << endl;
cout << myInt << endl;
}
void test3() {
MyInt myInt;
cout << myInt++ << endl;
cout << myInt << endl;
}
void test4() {
Li l1(10);
Li l2(20);
Li l3(30);
l3 = l2 = l1;
cout << *l1.age << endl; //10
cout << *l2.age << endl; //10
cout << *l3.age << endl; //10
}
void test5() {
Guanxi g1("lwt", 23);
Guanxi g2("lwt", 22);
if (g1 == g2) { // 如果不声明关系运算符重载,则这里编译不通过
cout << "两对象相等" << endl;
return;
}
cout << "两对象不相等!!!" << endl;
}
// 函数调用运算符重载
void test6(){
MyPrint myPrint;
myPrint.operator()("void operator()(string text)...");
MyAdd myAdd;
int res = myAdd.operator()(1,3);
printf("%d\n",res);
}
int main() {
test1(); // 全局左移运算符重载 =tostring()
printf("-------------------\n");
test2(); // 前置++ 递增运算符重载
printf("-------------------\n");
test3(); // 后置++
printf("-------------------\n");
test4(); // 赋值运算符重载
printf("-------------------\n");
test5(); // 关系运算符重载==
printf("-------------------\n");
test6(); //
return 0;
}
void test5() {
Guanxi g1("lwt", 23);
Guanxi g2("lwt", 22);
if (g1 == g2) { // 如果不声明关系运算符重载,则这里编译不通过
cout << "两对象相等" << endl;
return;
}
cout << "两对象不相等!!!" << endl;
}