C++类和对象之封装——学习案例二及其扩展(分文件编写)
案例二
本案例的核心要点是: 在类中可以让另一个类作为本类中的成员
# include<iostream>
using namespace std;
class Point{
public:
void setX(int x){
m_X = x;
}
int getX(){
return m_X;
}
void setY(int y){
m_Y = y;
}
int getY(){
return m_Y;
}
private:
int m_X; // 点的x坐标
int m_Y; // 点的y坐标
};
class Circle{
public:
// 注意设置和获取圆心的实现
void setCenter(Point center){
m_Center = center;
}
Point getCenter(){
return m_Center;
}
void setR(int r){
m_R = r;
}
int getR(){
return m_R;
}
private:
int m_R; //半径
Point m_Center; //圆心 ----------- 由于x和y通常是一个整体,所以这里将它们放到一个Point类里
};
// 判断点和圆的关系
void getRelation(Circle &c, Point &p){
// 计算点和圆心距离的平方
int c_X = c.getCenter().getX();
int c_Y = c.getCenter().getY();
int p_X = p.getX();
int p_Y = p.getY();
int distance = (c_X - p_X)*(c_X - p_X) + (c_Y - p_Y)*(c_Y - p_Y);
// 计算半径的平方
int r2 = c.getR() * c.getR();
// 判断关系
if (distance == r2){
cout << "点在圆上" << endl;
}
else if (distance > r2){
cout << "点在圆外" << endl;
}
else{
cout << "点在圆内" << endl;
}
}
int main(){
// 创建圆
Circle c;
c.setR(10);
Point center;
center.setX(10);
center.setY(0);
c.setCenter(center);
// 创建点
Point p;
p.setX(10);
p.setY(10);
// 判断关系
getRelation(c,p);
}
// summary:
// 本案例的核心要点是: 在类中可以让另一个类作为本类中的成员
案例二扩展
由于当项目比较大,创建的类也比较多时,如果只写在一个文件里阅读起来很麻烦,所以要分文件编写。
Step1.创建point.h
和point.cpp
:
point.h
STEPs:
0.开头加上#pragma once 以及包含常用头文件
1.把之前写好的Point类粘贴过来
2.把成员函数的实现删掉,只留声明,记得后面加;补全
3.成员变量保持不动
#pragma once //防止头文件重复包含
#include <iostream>
using namespace std;
class Point{
public:
void setX(int x);
int getX();
void setY(int y);
int getY();
private:
int m_X; // 点的x坐标
int m_Y; // 点的y坐标
};
point.cpp
STEPs:
1.把对应的.h文件包含进来
2.把Point类粘贴一次
3.只保留成员函数的实现, shift+tab调整缩进
4.由于下面这些函数写在这个文件里是全局函数,但我们知道setX getX等函数都是我们定义在类中的成员函数,
所以要在函数名前加上Point:: 告诉编译器这是Point类作用域下的函数
# include "point.h"
void Point::setX(int x){
m_X = x;
}
int Point::getX(){
return m_X;
}
void Point::setY(int y){
m_Y = y;
}
int Point::getY(){
return m_Y;
}
Step2.创建circle.h
和circle.cpp
:
circle.h
// Attention : 由于Circle类中还使用了Point类,所以要把point.h包含进来
#pragma once //防止头文件重复包含
#include <iostream>
using namespace std;
// Attention : 由于Circle类中还使用了Point类,所以要把point.h包含进来
# include "point.h"
class Circle{
public:
// 注意设置和获取圆心的实现
void setCenter(Point center);
Point getCenter();
void setR(int r);
int getR();
private:
int m_R; //半径
Point m_Center; //圆心 ---- 由于x和y通常是一个整体,所以这里将它们放到一个Point类里
};
circle.cpp
# include "circle.h"
void Circle::setCenter(Point center){
m_Center = center;
}
Point Circle::getCenter(){
return m_Center;
}
void Circle::setR(int r){
m_R = r;
}
int Circle::getR(){
return m_R;
}
Step3.在主文件开头包含两个.h文件:
# include "point.h"
# include "circle.h"
Step4.在VScode中运行:
如果直接用右上角的三角形▶️运行的话会报错:
这是因为:包含着报错的类的cpp文件没有被编译
参考stackoverflow:mac-os-vs-code-insiders-code-runner-undefined-symbols,
“因为Mac上的vscode不会自动链接相关联的文件,因此可能不得不在终端中运行代码。”
解决方案:
在终端依次运行以下两个命令
g++ 封装案例2.cpp circle.cpp point.cpp -o 封装案例2
./封装案例2
命令解析:
g++ 封装案例2.cpp circle.cpp point.cpp -o 封装案例2
封装案例2.cpp是我的主文件,circle.cpp和point.cpp是主文件关联的文件,封装案例2是编译生成的文件。
./封装案例2
运行编译生成的文件,即封装案例2。
于是就运行成功啦!✨