C++学习总结(3):友员与操作符重载
一、友员函数 friend
友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外
的普通函 数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元
的名称前加上 关键字 friend。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
using namespace std;
class Point;
class PointManager {
public:
double PointDistance(Point &p1, Point &p2);
};
class Point
{
public:
//声明全局函数 PointDistance 是我类Point类的一个友元函数。
//friend double PointDistance(Point &p1, Point &p2);
friend double PointManager::PointDistance(Point &p1, Point &p2);
Point(int x, int y) {
this->x = x;
this->y = y;
}
int getX()
{
return this->x;
}
int getY()
{
return this->y;
}
private:
int x;
int y;
};
double PointManager::PointDistance(Point &p1, Point &p2)
{
double dis;
int dd_x = p1.x - p2.x;
int dd_y = p1.y - p2.y;
dis = sqrt(dd_x*dd_x + dd_y *dd_y);
return dis;
}
int main(void)
{
Point p1(1, 2);
Point p2(2, 2);
//cout << PointDistance(p1, p2) << endl;
PointManager pm;
cout << pm.PointDistance(p1, p2) << endl;
return 0;
}
二、友员类 friend
有友员函数,也有友员类
看以下代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
{
this->a = a;
}
void printA() {
cout << "a = " << this->a << endl;
B objB(3000);
cout << objB.b << endl;
}
//声明一个友元类B
friend class B;
private:
int a;
};
class B
{
public:
B(int b)
{
this->b = b;
}
void printB() {
A objA(100);
cout << objA.a << endl;
cout << "b = " << this->b << endl;
}
friend class A;
private:
int b;
};
int main(void)
{
B bObj(200);
bObj.printB();
return 0;
}
尽量不要使用友员,它破坏了类的封装性和隐藏性。
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类 B 是类 A 的友元,类 A 不一定是类B 的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类 B 是类 A 的友元,类 C 是 B 的友元,类 C 不一定 是类 A 的友元,同样要看类中是否有相应的声明。
三、操作符重载
不可被重载的操作符 | 名称 |
---|---|
. | 成员选择符 |
.* | 成员对象选择符 |
:: | 域解析操作符 |
?: | 条件操作符 |
四、智能指针
智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,
c++常用的智能指针:
auto_ptr,本次暂时不介绍,c++ 11引入的三种,unique_ptr,shared_ptr,weak_ptr。
本次介绍auto_ptr的使用方式。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <memory> //使用智能指针,需要添加这个头文件
using namespace std;
class A
{
public:
A(int a)
{
cout << "A()..." << endl;
this->a = a;
}
void func()
{
cout << "a==" << this->a << endl;
}
~A()
{
cout << "~A()..." << endl;
}
private:
int a;
};
void test01()
{
auto_ptr<A> ptr(new A(10));
ptr->func();
(*ptr).func();//无需delete,也调用了析构函数
}
int main(void)
{
test01();
return 0;
}
运行结果如下: