C++:“类的声明”、“类的实现”分开写【类的声明(在.h头文件中);类的实现(在.cpp文件中)】【类的声明、实现也可以都写在.h头文件中,但是当多个源文件包含此头文件后,链接时报错:“多次定义”】
2023-09-27 14:20:39 时间
一、声明和实现为什么要分开写
现在开始写项目了,你会发现我们一般都要写一个cpp,对应的还得有一个h文件,那么为什么在C++中我们要这么做?
- .h就是声明,
- .cpp就是实现,
所谓分离式实现就是指:“声明”和“定义”分别保存在不同的文件中
- 声明保存在.h文件中;
- 定义保存在.cpp文件中;
那么将声明和定义分离有什么意义吗?
首先从非分离式(声明的同时给出定义)看,其内容一般保存在.h文件中,以供多个源文件引用。
但是如果将定义放.h头文件中,那么当多个源文件使用#include命令包含此类头文件便会在链接阶段出现“multiple definition”链接错误!
那么想让多个文件使用此头文件,又不引发链接的“multiple definition”错误该怎么办呢?
分离式的实现便可以解决这个问题。因为.h文件中只包含声明,即使被多个源文件引用也不会导致“multiple definition”链接错误。
所以分离式实现增强了命名空间的实用性。
二、案例
首先我们要实现确定一个“点”是否在“圆”内的功能;
所以我们需要两个类一个Point类,一个Circle类;
Point.h
在Point.h文件中编入代码,是关于一些成员函数的声明,其中#Pragma once表示只读一次。
#ifndef UNTITLED2_POINT_H
#define UNTITLED2_POINT_H
#pragma once
class Point {
public:
Point(); // 构造函数01:声明无参构造函数
Point(int x, int y); // 构造函数02:声明有参构造函数
int GetX(); // 声明函数:GetX
int GetY(); // 声明函数:GetY
private:
int x;
int y;
};
#endif //UNTITLED2_POINT_H
Point.cpp
Point.cpp文件中主要是Point.h中的函数的实现,要引入Point.h头文件,所以要写入#include"Point.h"。
#include "Point.h"
// 构造函数01: 无参构造函数的定义
Point::Point() {} //要加上作用域 Point::
// 构造函数02: 有参构造函数的定义
Point::Point(int x1, int y1) { //要加上作用域 Point::
x = x1;
y = y1;
}
//定义函数: GetX()
int Point::GetX() { //要加上作用域 Point::
return x;
}
//定义函数: GetY()
int Point::GetY() { //要加上作用域 Point::
return y;
}
Circle.h
因为用到了Point 类,所以也要#include "Point.h"
#ifndef UNTITLED2_CIRCLE_H
#define UNTITLED2_CIRCLE_H
#include "Point.h"
class Circle {
public:
Circle(); // 构造函数01:声明无参构造函数
Circle(Point o1, double r1, double s1, double c1); // 构造函数02:声明有参构造函数
double GetR(double r); // 声明函数:GetR
double GetS(); // 声明函数:GetS
double GetC(); // 声明函数:GetC
Point GetO(); // 声明函数:GetR
bool IsInCircle(Point p); // 声明函数:IsInCircle
private:
double m_r;
double m_s;
double m_c;
Point o;
};
#endif //UNTITLED2_CIRCLE_H
Circle.cpp
Circle.cpp主要是Circle.h 中的函数实现,IsInCiicle是实现点是否在圆内的函数。
#include "Circle.h"
#include "Point.h"
// 构造函数01:无参构造函数的定义
Circle::Circle() {}
// 构造函数02:有参构造函数的定义
Circle::Circle(Point o1, double r1, double s1, double c1) {
o = o1;
m_r = r1;
m_s = s1;
m_c = c1;
}
//定义函数: GetR()
double Circle::GetR(double r) //要写出作用域Circle::
{
m_r = r;
return m_r;
}
//定义函数: GetS()
double Circle::GetS() {
m_s = 3.14 * m_r * m_r;
return m_s;
}
//定义函数: GetC()
double Circle::GetC() {
m_c = 2 * 3.14 * m_r;
return m_c;
}
//定义函数: GetO()
Point Circle::GetO() {
return o;
}
//定义函数: IsInCircle()
bool Circle::IsInCircle(Point p) {
if (((p.GetX() - o.GetX()) * (p.GetX() - o.GetX()) + (p.GetY() - o.GetY()) * (p.GetY() - o.GetY())) <= m_r * m_r) {
return true;
} else {
return false;
};
}
main.cpp
#include<iostream>
#include"Circle.h"
#include"Point.h"
using namespace std;
int main() {
Point o = Point(0, 0);
Circle c1 = Circle(o, 5, 4, 3);
Point p1(3, 4);
bool b = c1.IsInCircle(p1);
cout << b << endl;
return 0;
}
相关文章
- C++ 获取 PE 文件导出表
- C/C++进程文件锁 之 fcntl函数的用法总结(非阻塞O_NONBLOCK)
- C++一些基本数据结构:字面常量、符号常量、枚举常量
- VC++动态链接库(DLL)编程深入浅出(四)
- 【C++】auto关键字
- 29 C++ - 友元
- 线程基础之JAVA和C++0x的特性
- C++中消息机制阻塞实验
- c++中的.hpp文件
- 《C++编程规范:101条规则、准则与最佳实践》——2.3编程中应知道何时和如何考虑可伸缩性
- 《C++面向对象高效编程(第2版)》——1.6 什么不是类
- C++ 11的移动语义
- 基于 C++ 实现日志文件压缩【100010585】
- 基于C++实现一个平面上的形状编辑程序【100010121】
- 基于 C++比较文件差异程序【100010117】
- 基于QT(C++)+CSV文件存储开发(WinForm)图书管理系统【100010008】
- C++编程——vector容器
- C++11 随机数学习
- C/C++读写csv文件
- Linux下配置C/C++开发环境-----Eclipse
- Visual studio C++桌面应用程序添加外部文件引用
- 145、【动态规划】leetcode ——70. 爬楼梯:暴力法+动态规划(C++版本)
- C++ Primer 学习笔记_104_特殊工具与技术 --嵌套类
- How to Install Eclipse C/C++ Development Tool--转
- 【C/C++】值传递和址传递区别解析
- C++ 手写一个高性能json生成与解析器
- C++实现INI文件读写