这是一个典型的计算几何问题,涉及到面向对象编程的核心思想——友元的概念以及类的设计。以下是基于题目的解析和解答:
---
### **题目分析**
我们需要设计两个核心类 `Point` 和 `Line` 来描述点和直线的关系,并利用**友元机制**实现点到线距离的计算。
#### 距离公式
给定点 `(x, y)` 到直线 `ax + by + c = 0` 的距离公式为:
\[ d = \frac{| ax_1 + by_1 + c |}{\sqrt{a^2 + b^2}} \]
其中 \( a^2 + b^2 \neq 0\) (由题目保证)。
---
### **解法**
我们按照题目要求分三种方法实现该功能:
---
#### **方法一:全局函数 (非成员函数)**
将 `dist` 定义为一个全局函数并作为 `Point` 和 `Line` 类的友元函数。
```cpp
#include <iostream>
#include <cmath>
using namespace std;
class Point;
class Line;
// 全局函数 dist
double dist(const Point& p, const Line& l);
class Point {
private:
double x, y;
public:
// 构造函数
Point(double _x = 0, double _y = 0): x(_x), y(_y) {}
friend double dist(const Point&, const Line&);
};
class Line {
private:
double a, b, c; // 直线方程 ax + by + c = 0
public:
// 构造函数
Line(double _a, double _b, double _c): a(_a), b(_b), c(_c) {}
friend double dist(const Point&, const Line&);
};
// 友元函数定义
double dist(const Point& p, const Line& l){
return abs(l.a * p.x + l.b * p.y + l.c) / sqrt(pow(l.a, 2) + pow(l.b, 2));
}
int main(){
double px, py, la, lb, lc;
cin >> px >> py;
cin >> la >> lb >> lc;
Point point(px, py);
Line line(la, lb, lc);
cout << "The distance is: " << fixed << setprecision(2) << dist(point, line) << endl;
return 0;
}
```
---
#### **方法二:成员函数 (Line 的成员函数)**
将 `dist` 定义为 `Line` 类的一个成员函数,并使其成为 `Point` 类的友元函数。
```cpp
#include <iostream>
#include <cmath>
using namespace std;
class Point;
class Line {
private:
double a, b, c;
public:
// 构造函数
Line(double _a, double _b, double _c): a(_a), b(_b), c(_c) {}
double dist(const Point&) const; // 成员函数原型
};
class Point {
private:
double x, y;
public:
// 构造函数
Point(double _x = 0, double _y = 0): x(_x), y(_y) {}
friend double Line::dist(const Point&) const; // 将 dist 声明为友元函数
};
// Member function definition for Line class
double Line::dist(const Point& p) const{
return abs(a*p.x + b*p.y + c) / sqrt(pow(a, 2) + pow(b, 2));
}
int main(){
double px, py, la, lb, lc;
cin >> px >> py;
cin >> la >> lb >> lc;
Point point(px, py);
Line line(la, lb, lc);
cout << "The distance is: " << fixed << setprecision(2) << line.dist(point) << endl;
return 0;
}
```
---
#### **方法三:友元类**
将整个 `Line` 类声明为 `Point` 类的友元类,直接访问其私有成员变量。
```cpp
#include <iostream>
#include <cmath>
using namespace std;
class Point;
class Line : public Line { // 或者省略继承修饰符,默认 private 继承也可以工作
private:
double a, b, c;
public:
// 构造函数
Line(double _a, double _b, double _c): a(_a), b(_b), c(_c) {}
double dist(const Point&) const; // 成员函数原型
};
class Point {
private:
double x, y;
public:
// 构造函数
Point(double _x = 0, double _y = 0): x(_x), y(_y) {}
friend class Line; // 整个 Line 类都是 Point 的友元类
};
// Member function definition for Line class
double Line::dist(const Point& p) const{
return abs(a*p.x + b*p.y + c) / sqrt(pow(a, 2) + pow(b, 2));
}
int main(){
double px, py, la, lb, lc;
cin >> px >> py;
cin >> la >> lb >> lc;
Point point(px, py);
Line line(la, lb, lc);
cout << "The distance is: " << fixed << setprecision(2) << line.dist(point) << endl;
return 0;
}
```
---
### §**相关问题§**:
1. 使用友元函数有哪些优点和缺点?
2. 如果不想使用友元机制,如何通过其他方式实现类似的功能?
3. 点到平面的距离该如何计算?