您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
第39讲-命名空间和模块化编程
发布时间:2021-05-22 18:01:30编辑:雪饮阅读()
接下来我们将重点讨论两个相互关联的简单概念:
第一个概念是模块化(modularization)一把程序划分成多个组成部分(即所谓的“模块”)一这是通过把程序代码分敬到多个文件里,等编译程序时再把那些文件重新组合在一起实现的。
第二个概念是命名空间(namespace)一这个概念相比起C语言是C++里新增加的东西,编写的程序越多、编写的程序越复杂,就越需要使用命名空间。
头文件的使用
只用一个源代码文件来保存程序的全部代码是可行的,但那会给编辑修改互作蒂来诸多不便。
我们可以借助于C++的预编译器和编译器的能力把一个复杂的应用程序划分成多个不同的文件,而仍保持它在内容和功能上的完整。
C++预处理器的#include括会提供了一种能够让编译器在编译主程序时把其他文件的内容包括进来的机制。例如用这个指令来包括像iostream头文件我们已经用过很多次了。
头文件的基本用途是提供必要的函数声明和类声明。比如string头文件就定义了字符串应该如何创建和使用。
头文件可以细分为系统头文件和自定义头文件。顾名思义,系统头文件定义的都是系统级功能,正式因为有了它们,C++代码才可以在某种特定的系统上运行。如果你想在你的程序使用这些功能,就必须把相应的头文件包括到你的程序里来。
系统头文件的另一个重要作用是保证C++代码的可移植性,确保同样的C++代码在不同的操作系统上做同样的事情。
例如为Mac定义的cout和为Windows定义的cout做的事情一样,但内部的具体实现不见得一样。
在#include指会里,系统头文件的文件名要放在尖括号里给出,这是告诉编译器:应该到“标准的”地点寻找这个文件:
#include <stdio.h>
在#include指令里,自定义头文件的文件名要放在双引号里给出:
#include "test.h"
头文件是一些以.h作为扩展名的标准文本文件。一般情况下,都应该把自定义的头文件和其余的程序文件放在同一个子目录里,或者在主程序目录下专门创建一个子文件夹来集中存放它们。你可以用头文件来保存程序的任何一段代码,如函数或类的声明,但一定不要用头文件来保存它们的实现!
与标准的C++源代码文件相比,在头文件里应该使用更多的注释。
绝大多数头文件是通用型的,不属于任何特定的程序,所以至少把它的用途和用法描述清楚。
应该在注释里说明的内容包括:
创建日期,文件用途,创建者姓名,最后一次修改日期,有什么限制和前提案件等等。
另外头文件里的每一个类和函数也应该有说明。
头文件举例:Rational.h
在code blocks种建立头文件,它虽然看似结构上不与.cpp在直接一个同级目录,但实际上最终落地文件路径是相同的。
在code blocks种建立头文件时候和之前建立cpp文件一样,只是建立时候要选择这个C/C++ header
这里选择输入一个绝对路径,一般的都是同项目路径在一起,没有尝试过不在一起的情况,不过感觉code blocks应该会为我们自动链接吧。
最终落地文件相同
那么这里是以重载四则运算符以最大公约数进行简化进而进行分数的四则运算的实例来演示。
头:
这里放的是我们实际要用到的自定义类的定义(个人感觉,实现也是可以在这里写好的,不过甲鱼既然说不行,暂且就按他的来咯)
Rational.h:
//Rational.h
//Create by C++快速入门
//这个头文件声明了有理数类(Rational class)
//类里边对四则运算进行重载,以实现分数运算
#include <iostream>
class Rational
{
public:
Rational(int num, int denom); // num = 分子, denom = 分母
Rational operator+(Rational rhs); // rhs == right hand side
Rational operator-(Rational rhs);
Rational operator*(Rational rhs);
Rational operator/(Rational rhs);
void print();
private:
void normalize(); // 负责对分数的简化处理
int numerator; // 分子
int denominator; // 分母
};
然后主要的程序文件cpp种就是对其类的具体定义以及其它逻辑的实现:
main.cpp:
#include <iostream>
#include <string>
#include "Rational.h"
using namespace std;
// num = 分子, denom = 分母
Rational::Rational(int num,int denomi)
{
numerator=num;
denominator=denomi;
normalize();
}
void Rational::normalize()
{
if(denominator<0)
{
numerator=-numerator;
denominator=-denominator;
}
//欧几里得算法
int a = abs(numerator);
int b = abs(denominator);
//求两个数的最大公约数
while(b>0)
{
int t=a%b;
a=b;
b=t;
}
//分子,分母分别除以最大公约数,得到最简式子
numerator/=a;
denominator/=a;
}
//a c a*d+b*c
//— + — = ——————
//b d b*d
Rational Rational::operator+(Rational x)
{
int a=numerator;
int b=denominator;
int c=x.numerator;
int d=x.denominator;
int e=a*d+c*b;
int f=b*d;
return Rational(e,f);
}
Rational Rational::operator-(Rational x)
{
x.numerator=-x.numerator;//减相当于加负数
return operator+(x);
}
//a c a*c
//— * — = ——————
//b d b*d
Rational Rational::operator*(Rational x)
{
int a=numerator;
int b=denominator;
int c=x.numerator;
int d=x.denominator;
int e=a*c;
int f=b*d;
return Rational(e,f);
}
/*
分数除法的计算法则为:甲数除以乙数(0除外),等于甲数乘乙数的倒数。
a c a*d
— / — = ——————
b d b*c
*/
Rational Rational::operator/(Rational x)
{
int a=numerator;
int b=denominator;
int c=x.numerator;
int d=x.denominator;
int e=a*d;
int f=b*c;
return Rational(e,f);
}
void Rational::print()
{
if(numerator%denominator==0)
cout<<numerator/denominator;
else
cout<<numerator<<'/'<<denominator;
}
int main()
{
Rational f1(2,16);
Rational f2(7,8);
//加法
Rational resadd=f1+f2;
f1.print();
cout<<'+';
f2.print();
cout<<'=';
resadd.print();
cout<<'\n';
//减法
Rational ressub=f1-f2;
f1.print();
cout<<'-';
f2.print();
cout<<'=';
ressub.print();
cout<<'\n';
//乘法
Rational resmul=f1*f2;
f1.print();
cout<<'*';
f2.print();
cout<<'=';
resmul.print();
cout<<'\n';
//除法
Rational resc=f1/f2;
f1.print();
cout<<'/';
f2.print();
cout<<'=';
resc.print();
cout<<'\n';
return 0;
}
编译运行结果如:
1/8+7/8=1
1/8-7/8=-3/4
1/8*7/8=7/64
1/8/7/8=1/7
Process returned 0 (0x0) execution time : 0.023 s
Press any key to continue.
关键字词:命名空间,分数
上一篇:第37讲-高级强制类型转换
下一篇:第40讲-命名空间和模块化编程2