@@ -671,6 +671,149 @@ int main()
671671
672672添加静态成员可以增强 ` Date ` 类的功能性和实用性,特别是当需要跟踪或共享与日期相关的通用信息时。
673673
674+
675+
676+ #### 举例
677+
678+ ** 静态函数实现**
679+
680+ ``` cpp
681+ class Point {
682+ private:
683+ double x, y;
684+
685+ public:
686+ Point(double x, double y) : x(x), y(y) {}
687+
688+ static double distance(const Point& point1, const Point& point2) {
689+ return sqrt(pow(point1.x - point2.x, 2) + pow(point1.y - point2.y, 2));
690+ }
691+ };
692+
693+ ```
694+
695+ 调用方式:
696+
697+ ``` cpp
698+ Point p1 (1.0, 2.0);
699+ Point p2(4.0, 6.0);
700+ double dist = Point::distance(p1, p2);
701+
702+ ```
703+
704+ **非静态函数实现**
705+
706+ ```cpp
707+ class Point {
708+ private:
709+ double x, y;
710+
711+ public:
712+ Point(double x, double y) : x(x), y(y) {}
713+
714+ double distance(const Point& other) const {
715+ return sqrt(pow(x - other.x, 2) + pow(y - other.y, 2));
716+ }
717+ };
718+
719+ ```
720+
721+ 调用方式:
722+
723+ ``` cpp
724+ Point p1 (1.0, 2.0);
725+ Point p2(4.0, 6.0);
726+ double dist = p1.distance(p2);
727+ ```
728+
729+
730+
731+ **1. 非静态函数需要依赖对象实例**
732+
733+ - **当前实现(`static`)**:
734+ - `distance` 是一个静态成员函数,与具体的 `Point` 对象无关。
735+ - 调用时可以直接通过类名调用,例如:`Point::distance(point1, point2)`。
736+ - 静态函数不能访问类的非静态成员变量(如 `x` 和 `y`),因为它不依赖于任何对象实例。
737+
738+ - **如果去掉 `static`**:
739+ - `distance` 将变成一个非静态成员函数,必须通过某个 `Point` 对象调用。
740+ - 例如:`point1.distance(point2)`,此时 `distance` 函数的第一个参数隐式绑定到调用它的对象 `point1`。
741+
742+ **2. 函数签名的变化**
743+
744+ - **当前签名(静态函数)**:
745+ ```cpp
746+ static double distance(const Point& point1, const Point& point2);
747+
748+ ```
749+ - 需要显式传入两个 ` Point ` 对象作为参数。
750+
751+ - ** 去掉 ` static ` 后的签名** :
752+
753+ ``` cpp
754+ double distance (const Point& other) const;
755+
756+ ```
757+ - 只需要传入一个 `Point` 对象作为参数,另一个 `Point` 对象是调用该函数的对象(`this` 指针)。
758+
759+ **3. 使用方式的变化**
760+
761+ **当前(静态函数)**
762+
763+ 调用方式:
764+
765+ ```cpp
766+ Point point1(1.0, 2.0);
767+ Point point2(4.0, 6.0);
768+ double dist = Point::distance(point1, point2); // 通过类名调用
769+
770+ ```
771+
772+ ** 去掉 ` static ` 后(非静态函数)**
773+
774+ 调用方式:
775+
776+ ``` cpp
777+ Point point1 (1.0, 2.0);
778+ Point point2(4.0, 6.0);
779+ double dist = point1.distance(point2); // 通过对象调用
780+
781+ ```
782+
783+ **4. 设计上的影响**
784+
785+ - **静态函数的优点**:
786+ - 逻辑上更清晰:`distance` 函数的功能是计算两点之间的距离,与某个具体的 `Point` 对象无关,因此设计为静态函数更符合直觉。
787+ - 更灵活:可以直接通过类名调用,而不需要依赖某个对象实例。
788+
789+ - **非静态函数的优点**:
790+ - 如果 `distance` 函数的逻辑需要频繁使用调用对象的成员变量(如 `x` 和 `y`),设计为非静态函数可能更方便。
791+ - 例如,调用 `point1.distance(point2)` 时,`point1` 的坐标可以直接通过 `this` 指针访问。
792+
793+ **5. 性能上的影响**
794+
795+ - **静态函数**:
796+ - 不需要传递隐式的 `this` 指针,调用开销略低。
797+ - 更适合与类的实例无关的功能。
798+
799+ - **非静态函数**:
800+ - 需要传递隐式的 `this` 指针,调用开销略高。
801+ - 适合需要访问调用对象的成员变量的功能。
802+
803+ **6. 结论**
804+
805+ - **保留 `static`**:
806+ - 如果 `distance` 函数的逻辑与具体的 `Point` 对象无关(如当前实现),设计为静态函数更合理。
807+ - 适合计算两点之间的距离这种独立于对象的功能。
808+
809+ - **去掉 `static`**:
810+ - 如果希望通过调用对象直接计算与另一个点的距离,设计为非静态函数更方便。
811+ - 适合需要频繁访问调用对象的成员变量的功能。
812+
813+ 在上面的场景中,`distance` 函数的逻辑与具体的 `Point` 对象无关,因此保留 `static` 是更好的选择。
814+
815+
816+
674817### 6.3 `static const` 成员
675818
676819`static const` 成员是C++类中的特殊成员,它们结合了静态成员的共享性和常量成员的不可修改性。这种成员在所有对象间共享,并且在程序执行期间其值不会改变。
@@ -852,7 +995,7 @@ int main() {
852995
853996## 8 作业
854997
855- 按需求设计一个圆类输入圆的半径和圆柱的高 ,依次输出圆周长、圆面积、圆球表面积、圆柱体积(以空格分隔,π取 3.14)。
998+ 设计一个圆类,输入圆的半径和圆柱的高 ,依次输出圆周长、圆面积、圆球表面积、圆柱体积(以空格分隔,π取 3.14)。
856999```cpp
8571000#include <iostream>
8581001
@@ -866,28 +1009,28 @@ private:
8661009 float circumference; //圆的周长
8671010 float volume; //圆的体积
8681011 float surface; //圆的表面积
869- static const float PI = 3.14 ; //圆周率
1012+ static const float PI; // 静态常量 圆周率
8701013
8711014public:
8721015 circle(float r = 0, float h = 0); //构造函数
8731016 ~circle();
874-
1017+
8751018 // 计算圆周长
8761019 float calculateCircumference();
877-
1020+
8781021 // 计算圆面积
8791022 float calculateArea();
880-
1023+
8811024 // 计算圆球表面积
8821025 float calculateSphereArea();
883-
1026+
8841027 // 计算圆柱体积
8851028 float calculateCylinderVolume();
886-
887- // 设置半径和高
888- void setValues(float r, float h);
8891029};
8901030
1031+ // 在类外初始化静态常量
1032+ const float circle::PI = 3.14;
1033+
8911034circle::circle(float r, float h)
8921035{
8931036 radius = r;
@@ -922,31 +1065,116 @@ float circle::calculateCylinderVolume()
9221065 return volume;
9231066}
9241067
925- void circle::setValues(float r, float h)
926- {
927- radius = r;
928- high = h;
929- }
930-
9311068int main()
9321069{
9331070 float radius, high;
934-
1071+
9351072 // 输入半径和高
9361073 std::cin >> radius >> high;
937-
1074+
9381075 // 创建circle对象并设置值
9391076 circle c(radius, high);
940-
1077+
9411078 // 计算并输出结果,以空格分隔
9421079 std::cout << c.calculateCircumference() << " "
943- << c.calculateArea() << " "
944- << c.calculateSphereArea() << " "
945- << c.calculateCylinderVolume() << std::endl;
946-
1080+ << c.calculateArea() << " "
1081+ << c.calculateSphereArea() << " "
1082+ << c.calculateCylinderVolume() << std::endl;
1083+
9471084 return 0;
9481085}
9491086
9501087```
9511088
952- 编写C++程序完成以下功能: 1)定义一个 Point 类,其属性包括点的坐标,提供计算两点之间距离的方法;2)定义一个圆形类, a.其属性包括圆心和半径; b.创建两个圆形对象,提示用户输入圆心坐标和半径,判断两个圆是否相交,并输出结果。
1089+
1090+
1091+ 1)定义一个 Point 类,其属性包括点的坐标,提供计算两点之间距离的方法;2)定义一个圆形类, a.其属性包括圆心和半径; b.创建两个圆形对象,提示用户输入圆心坐标和半径,判断两个圆是否相交,并输出结果。
1092+
1093+ ** Point.h**
1094+
1095+ ``` cpp
1096+ #pragma once
1097+ class Point
1098+ {
1099+
1100+ private:
1101+ double x;
1102+ double y;
1103+
1104+ public:
1105+ Point(double x, double y) : x(x), y(y)
1106+ {
1107+ }
1108+
1109+ static double distance(const Point& point1, const Point& point2)
1110+ {
1111+ return sqrt(pow(point1.x - point2.x, 2) + pow(point1.y - point2.y, 2));
1112+ }
1113+ };
1114+
1115+
1116+ ```
1117+
1118+ ** Circle.h**
1119+
1120+ ``` cpp
1121+ #pragma once
1122+ #include " Point.h"
1123+ class Circle
1124+ {
1125+ private:
1126+ Point center; // 圆心
1127+ double radius; // 半径
1128+
1129+ public:
1130+ // 构造函数
1131+ Circle (const Point& center, double radius) : center(center), radius(radius) {}
1132+
1133+ // 获取圆心
1134+ const Point& getCenter() const { return center; }
1135+
1136+ // 获取半径
1137+ double getRadius() const { return radius; }
1138+
1139+ // 判断两个圆是否相交
1140+ static bool isIntersecting(const Circle& circle1, const Circle& circle2) {
1141+ double distance = Point::distance(circle1.getCenter(), circle2.getCenter());
1142+ return distance <= (circle1.getRadius() + circle2.getRadius());
1143+ }
1144+ };
1145+
1146+ ```
1147+
1148+ **GeometryUtils.cpp**
1149+
1150+ ```cpp
1151+ #include <iostream>
1152+ #include "Circle.h"
1153+
1154+ int main() {
1155+ // 提示用户输入第一个圆的圆心坐标和半径
1156+ double x1, y1, r1;
1157+ std::cout << "Enter the center (x, y) and radius of the first circle: ";
1158+ std::cin >> x1 >> y1 >> r1;
1159+
1160+ // 提示用户输入第二个圆的圆心坐标和半径
1161+ double x2, y2, r2;
1162+ std::cout << "Enter the center (x, y) and radius of the second circle: ";
1163+ std::cin >> x2 >> y2 >> r2;
1164+
1165+ // 创建两个圆形对象
1166+ Circle circle1(Point(x1, y1), r1);
1167+ Circle circle2(Point(x2, y2), r2);
1168+
1169+ // 判断两个圆是否相交
1170+ if (Circle::isIntersecting(circle1, circle2)) {
1171+ std::cout << "The two circles intersect." << std::endl;
1172+ }
1173+ else {
1174+ std::cout << "The two circles do not intersect." << std::endl;
1175+ }
1176+
1177+ return 0;
1178+ }
1179+ ```
1180+
0 commit comments