在程序里,有些私有属性,也想让类外特殊的一些函数或者类进行访问,就需要利用友元技术
友元的目的就是让一个函数或者类 访问另一个类中的私有成员
友元的关键字为 friend
三种实现:
1.全局函数做友元
2.类做友元
3.成员函数做友元
ex1: 全局函数做友元
class Building {
friend void goodfriend(Building* build); // 全局函数实现友元
public:
string m_sitroom;
Building() {
m_bedroom = "卧室";
m_sitroom = "客厅";
}
private:
string m_bedroom;
};
//全局函数
void goodguy(Building * build) {
cout << "朋友在访问" << build->m_sitroom << endl;
}
void goodfriend(Building* build) {
cout << "好朋友在访问" << build->m_sitroom << endl;
cout << "好朋友在访问" << build->m_bedroom << endl;
}
void test01() {
Building build;
goodguy(&build);
goodfriend(&build);
}
int main() {
test01();
}
2.类做友元
class Building {
// 让goodgay做友元,从而可以访问私有属性
friend class goodgay;
public:
string m_sitroom;
Building();
private:
string m_bedroom;
};
//类外写成员函数
Building::Building() {
m_bedroom = "卧室";
m_sitroom = "客厅";
}
class goodfiren {
public:
void visit() {
cout << "好朋友参观中" << build->m_sitroom << endl;
}; // 参观函数,访问building的属性
Building* build;
goodfiren() {
build = new Building;
}
};
class goodgay {
public:
void visit() {
cout << "好基友参观中" << build->m_bedroom << endl;
cout << "好基友参观中" << build->m_sitroom << endl;
}; // 参观函数,访问building的属性
Building* build;
goodgay() {
build = new Building;
}
};
void main() {
goodfiren g;
g.visit();
goodgay g2;
g2.visit();
}
3.成员方法做友元
#includeusing namespace std; #include class Building; class goodgay { public: void visit(); void visit2(); goodgay(); Building* build; }; class Building { // 让goodgay做友元,从而可以访问私有属性 friend void goodgay::visit2(); public: string m_sitroom; Building(); private: string m_bedroom; }; //类外写成员函数 Building::Building() { m_bedroom = "卧室"; m_sitroom = "客厅"; } void goodgay::visit() { cout << "好基友参观中" << build->m_sitroom << endl; }; // 参观函数,访问building的属性 void goodgay::visit2() { cout << "好基友参观中" << build->m_bedroom << endl; cout << "好基友参观中" << build->m_sitroom << endl; }; // 参观函数,访问building的属性 goodgay::goodgay() { build = new Building; } void main() { goodgay g2; //g2.visit(); g2.visit2(); }
C++ 的运算符重载
加减乘除的重载, 很简单,有两种,一种是成员函数重载,一种是全局函数重载
class Test {
public :
int time;
int age;
Test() {
time = 10;
age = 20;
}
//成员函数重载
Test operator-(Test t3) {
Test t2;
t2.age = this->age - t3.age;
t2.time = this->time - t3.time;
return t2;
}
};
// 全局函数重载
Test operator+(Test& t1, Test& t2) {
Test t3;
t3.time = t1.time + t2.time;
t3.age = t1.age + t2.age;
return t3;
}
C++ 左移运算符重载
ostream& operator<<(ostream& out, Test& t) {
out << "t = " << t.age << t.time;
return out;
}
++ 运算符重载
赋值运算符重载:
还是涉及深浅拷贝问题,以下代码会报错
class Person {
public:
int *age;
Person(int age) {
this->age = new int(age); // 在堆区开辟了一块内存空间
}
int time;
~Person() {
if (age != NULL) {
delete age;
age == NULL;
}
}
};
int main() {
Person p1(18);
Person p2(15);
cout << *p1.age << *p2.age << endl;
p1 = p2;
cout << *p1.age << *p2.age << endl;
}
原因是深浅拷贝问题,释放p2时,便已经清空了一次p2.age的地址,而p1.age 和 p2.age 指向同一块,清除p1时会报错
如何处理? 重载赋值运算符
#includeusing namespace std; #include class Person { public: int *age; Person(int age) { this->age = new int(age); // 在堆区开辟了一块内存空间 } int time; ~Person() { if (age != NULL) { delete age; age == NULL; } } Person& operator=(Person& p) { //age = p.age 这是编译器自动提供的浅拷贝 if (age != NULL) { delete age; age = NULL; } age = new int(*p.age); return *this; } }; int main() { Person p1(18); Person p2(15); cout << *p1.age << *p2.age << endl; p1 = p2; cout << *p1.age << *p2.age << endl; Person p3(5); p3 = p2 = p1; cout << *p1.age << *p2.age << *p3.age < 函数调用运算符重载 仿函数
()也可以发生重载,由于重载后的使用方式非常像函数的调用,称之为仿函数,没有固定的写法,相当灵活void operator()(string p) { cout << p << endl; }



