C++分文件编写实战:点与圆的位置关系判断
C++中通过分文件编写管理类结构是提升代码可维护性的关键技能。本文以判断点与圆的相对位置为例,演示如何拆分Point类与Circle类的声明头文件和实现源文件,并通过引用传参与封装方法计算两点间距离,从而得出点在圆内、圆上或圆外的结论。
创建圆心类
在面向对象设计中,首先定义基础的“圆心”概念。我们将横纵坐标设为私有成员,以防止外部直接修改,同时提供公共的成员方法用于赋值和读取数据。这种封装方式是处理复杂数据结构的基础。
第1步:定义 Point 类的接口 (point.h)
目的:建立类的结构蓝图,包含属性声明和方法原型。
在此文件中,使用 #pragma once 防止头文件重复包含,引入标准库并定义命名空间。关键在于设置私有成员变量 m_x 和 m_y,并声明对应的 setter 和 getter 方法:
#pragma once
#include<iostream>
using namespace std;
// 创建圆心类
class Point
{
public:
void setM_x(int x);
int getM_x();
void setM_y(int y);
int getM_y();
private:
int m_x;
int m_y;
};
第2步:实现 Point 类的具体逻辑 (point.cpp)
目的:完成类内部成员函数的功能逻辑。
该文件负责具体的业务处理。引入 "point.h" 后,在方法名前添加 :: 作用域解析符,明确表明这些方法属于 Point 类。简单的赋值与返回值逻辑如下:
#include"point.h"
void Point::setM_x(int x)
{
m_x = x;
}
int Point::getM_x()
{
return m_x;
}
void Point::setM_y(int y)
{
m_y = y;
}
int Point::getM_y()
{
return m_y;
}
创建圆类
圆由圆心和半径两个要素构成。因此,Circle 类需要持有 Point 类型的对象作为成员变量,并利用之前定义的 Point 类接口进行交互。
第3步:定义 Circle 类的接口 (Circle.h)
目的:构建复合对象的抽象结构。
除了常规的半径属性外,这里引入了 "point.h" 头文件。我们在 Circle 类中创建了 m_center 成员变量。特别注意 setCenter 方法采用了引用传参 Point ¢er,这可以避免对象的深拷贝,提高传递效率。获取圆心时则返回一个 Point 对象。
#pragma once
#include<iostream>
#include "point.h"
using namespace std;
// 创建 Circle 类
class Circle
{
public:
void setM_r(int r);
int getM_r();
void setCenter(Point ¢er);
Point getCenter();
private:
int m_r;
Point m_center;
};
第4步:实现 Circle 类的具体逻辑 (Circle.cpp)
目的:实现圆心对象的整体转移及半径管理。
在 setCenter 的实现中,直接使用了 = 操作符,这会调用 Point 类的默认拷贝构造函数来更新内部的圆心对象:
#include"Circle.h"
void Circle::setM_r(int r)
{
m_r = r;
}
int Circle::getM_r()
{
return m_r;
}
void Circle::setCenter(Point ¢er)
{
m_center = center;
}
Point Circle::getCenter()
{
return m_center;
}
判断点圆关系函数
核心算法基于解析几何原理。我们比较“点到圆心的距离”与“半径”的大小。为了消除浮点数运算带来的精度损耗和提高效率,通常比较它们的平方值即可。
如果 (dx*dx + dy) > r*r,则点在圆外;等于则点在圆上;小于则点在圆内。以下代码展示了如何通过链式调用获取坐标并进行比较:
void relative(Circle& c, Point& p)
{
// 圆心到点距离的平方为distance
int distance =
(c.getCenter().getM_x() - p.getM_x()) * (c.getCenter().getM_x() - p.getM_x()) +
(c.getCenter().getM_y() - p.getM_y()) * (c.getCenter().getM_y() - p.getM_y());
// 半径的平方 rDistance
int rDistance = c.getM_r() * c.getM_r();
if (distance > rDistance) cout << "点在圆外" << endl;
else if (distance == rDistance) cout << "点在圆上" << endl;
else cout << "点在圆内" << endl;
}
最终实现与测试
在主函数中,我们将上述组件组合起来。流程包括:创建对象实例 → 接收用户输入 → 调用 Set 方法初始化数据 → 执行相对位置判断。
#include"Circle.h"
void relative(Circle& c, Point& p)
{
// 圆心到点距离的平方为distance
int distance =
(c.getCenter().getM_x() - p.getM_x()) * (c.getCenter().getM_x() - p.getM_x()) +
(c.getCenter().getM_y() - p.getM_y()) * (c.getCenter().getM_y() - p.getM_y());
// 半径的平方 rDistance
int rDistance = c.getM_r() * c.getM_r();
if (distance > rDistance) cout << "点在圆外" << endl;
else if (distance == rDistance) cout << "点在圆上" << endl;
else cout << "点在圆内" << endl;
}
int main()
{
int x = 0, y = 0, a = 0, b = 0, r = 0;
Circle C;
Point center, P;
cout << "圆心横坐标 x 为:"; cin >> x; cout << endl;
cout << "圆心纵坐标 y 为:"; cin >> y; cout << endl;
center.setM_x(x);
center.setM_y (y);
C.setCenter(center);
cout << "此圆 半径 r 为:"; cin >> r; cout << endl;
C.setM_r(r);
cout << "点横坐标 x 为:"; cin >> a; cout << endl;
cout << "点纵坐标 y 为:"; cin >> b; cout << endl;
P.setM_x(a);
P.setM_y(b);
relative(C, P);
}
总结
本例完整演示了C++中从单一源文件向多文件工程化结构的转变过程。通过五个文件(Point.h/cpp 和 Circle.h/cpp 以及主程序),实现了逻辑的高内聚和低耦合。这种方法在处理更复杂的项目时能够显著降低代码的管理难度,是学习面向对象设计模式的良好起点。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









