Loading

C++类和对象之封装——学习案例二及其扩展(分文件编写)

案例二

image
本案例的核心要点是: 在类中可以让另一个类作为本类中的成员

# 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.hpoint.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.hcircle.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中运行:

如果直接用右上角的三角形▶️运行的话会报错:
image这是因为:包含着报错的类的cpp文件没有被编译
参考stackoverflow:mac-os-vs-code-insiders-code-runner-undefined-symbols
“因为Mac上的vscode不会自动链接相关联的文件,因此可能不得不在终端中运行代码。”

解决方案:
在终端依次运行以下两个命令
g++ 封装案例2.cpp circle.cpp point.cpp -o 封装案例2
./封装案例2
image

命令解析:
g++ 封装案例2.cpp circle.cpp point.cpp -o 封装案例2
封装案例2.cpp是我的主文件,circle.cpp和point.cpp是主文件关联的文件,封装案例2是编译生成的文件。
image./封装案例2
运行编译生成的文件,即封装案例2。

于是就运行成功啦!✨

posted @ 2021-11-24 22:48  少年人永远倔强  阅读(135)  评论(0编辑  收藏  举报