关闭

C++多文件程序

标签: c++
234人阅读 评论(0) 收藏 举报
分类:
一.C++程序的多文件结构
       之前鸡啄米给大家看了很多比较完整的C++程序的例子,大家可能发现了,它们的结构基本上可以分为三个部分:类的声明、类的成员函数的实现和主函数。因为代码比较少,所以可以把它们写在一个文件中,但是我们实际进行软件开发时,程序会比较复杂,代码量比较大,
       一个程序按结构至少可以划分为三个文件:类的声明文件(*.h文件)、类的实现文件(*.cpp文件)和主函数文件(使用到类的文件),如果程序更复杂,我们会为每个类单独建一个声明文件和一个实现文件。这样我们要修改某个类时就直接找到它的文件修改即可,不需要其他的文件改动。
       鸡啄米在第十九讲中讲生存期时有个时钟类的例子,现在鸡啄米给大家看下将那个程序按照上面说的结构分到三个文件里:
       // 文件1:Clock类的声明,可以起名为Clock.h
       #include <iostream>
       using namespace std;
       class Clock //时钟类声明
       {
       public: //外部接口
                   Clock();
                   void SetTime(int NewH, int NewM, int NewS);   //三个形参均具有函数原型作用域
                   void ShowTime();
                  ~Clock(){}
       private: //私有数据成员
                   int Hour,Minute,Second;
       };
       // 文件2:Clock类的实现,可以起名为Clock.cpp
       #include "Clock.h"
       //时钟类成员函数实现
       Clock::Clock() //构造函数
       {
                  Hour=0;
                  Minute=0;
                  Second=0;
       }
       void Clock::SetTime(int NewH,int NewM,int NewS)
       {
                  Hour=NewH;
                  Minute=NewM;
                  Second=NewS;
       }
       void Clock::ShowTime()
       {
                 cout<<Hour<<":"<<Minute<<":"<<Second<<endl;
       }
      // 文件3:主函数,可以起名为main.cpp
       #include "Clock.h"
       //声明全局对象g_Clock,具有文件作用域,静态生存期
       Clock g_Clock;
       int main() //主函数
       {
                  cout<<"文件作用域的时钟类对象:"<<endl;
                  //引用具有文件作用域的对象:
                  g_Clock.ShowTime();
                  g_Clock.SetTime(10,20,30);
 
                  Clock myClock(g_Clock);    //声明具有块作用域的对象myClock,并通过默认拷贝构造函数用g_Clock初始化myClock
                  cout<<"块作用域的时钟类对象:"<<endl;
                  myClock.ShowTime(); //引用具有块作用域的对象
       }
       在vs2010中如何生成这三个文件呢?我们可以点菜单中Project->Add Class,在弹出的对话框中选择c++ class,然后由弹出个对话框,在class name处填上类名点finish就可以了,这样.h文件和.cpp文件会自动生成,我们也可以点Project->Add New Item,在弹出的对话框中选择Header File(.h)或C++ File(.cpp)来生成.h文件或.cpp文件。
      Clock.cpp和main.cpp都使用#include "Clock.h"把类Clock的头文件Clock.h包含进来。#include指令的作用就是将#include后面的文件嵌入到当前源文件该点处,被嵌入的文件可以是.h文件也可以是.cpp文件。如果不包含Clock.h,Clock.cpp和main.cpp就不知道Clock类的声明形式,就无法使用此类,所以所有使用此类的文件都应该包含声明它的头文件。关于#include指令下面鸡啄米会讲。
       上面的程序在编译时,由Clock.cpp和Clock.h编译生成Clock.obj,由main.cpp和Clock.h编译生成main.obj,然后就是链接过程,Clock.obj和main.obj链接生成main.exe可执行文件。如果我们只修改了类的实现文件,那么只需重新编译Clock.cpp并链接就可以,别的文件不用管,这样就提高了效率。在Windows系统中的C++程序用工程来管理多文件结构,而Unix系统一般用make工具管理,如果大家从事Unix系统软件开发,就需要自己写make文件。
       二.编译预处理程序
       编译器在编译源程序以前,要由预处理程序对源程序文件进行预处理。预处理程序提供了一些编译预处理指令和预处理操作符。预处理指令都要由“#”开头,每个预处理指令必须单独占一行,而且不能用分号结束,可以出现在程序文件中的任何位置。
       1.#include指令
       #include指令也叫文件包含指令,用来将另一个源文件的内容嵌入到当前源文件该点处。其实我们一般就用此指令来包含头文件。#include指令有两种写法:
       #include <文件名>
       使用这种写法时,会在C++安装目录的include子目录下寻找<>中标明的文件,通常叫做按标准方式搜索。
       #include "文件名"
       使用这种写法时,会先在当前目录也就是当前工程的目录中寻找""中标明的文件,若没有找到,则按标准方式搜索。
       2.#define和#undef指令
       如果你学过C语言,就会知道用#define可以定义符号常量,比如,#define PI 3.14 这条指令定义了一个符号常量PI,它的值是3.14。C++也可以这样定义符号常量,但一般更常用的是在声明时用const关键字修饰。C语言还用#define定义参数宏,来实现简单的函数运算,比如,#define add(x,y) (x+y) 这条指令说明如果我们用到add(1,2)则预处理后就会用(1+2)代替,C++中一般用内联函数来实现。
       #undef用来删除由#define定义的宏,使其不再起作用。
       3.条件编译指令
       用条件编译指令可以实现某些代码在满足一定条件时才会参与编译,这样我们可以利用条件编译指令将同一个程序在不同的编译条件下生成不同的目标代码。例如,我们可以在调试程序时加入一些调试语句,用条件编译指令控制只有在debug模式下这些调试语句才参与编译,而在release模式下不参与编译。
       条件编译指令有5中形式:
       a.第一种形式:
       #if  常量表达式        
                程序正文        //当“ 常量表达式”非零时本程序段参与编译
       #endif
       b.第二种形式:
       #if   常量表达式
                 程序正文1       //当“ 常量表达式”非零时本程序段参与编译
       #else
                 程序正文2       //当“ 常量表达式”为零时本程序段参与编译
       #endif
       c.第三种形式:
       #if 常量表达式1
                 程序正文1        //当“ 常量表达式1”非零时本程序段参与编译
       elif 常量表达式2
                程序正文2        //当“常量表达式1”为零、“ 常量表达式2”非零时本程序段参与编译
        ...
       elif 常量表达式n
                程序正文n        //当“常量表达式1”、...、“常量表达式n-1”均为零、“ 常量表达式n”非零时本程序段参与编译
       #else
                程序正文n+1      //其他情况下本程序段参与编译
       #endif
       d.第四种形式:
       #ifdef 标识符
                程序段1
       #else
                程序段2
       #endif
       如果“标识符”经#defined定义过,且未经undef删除,则编译程序段1,否则编译程序段2。
       e.第五种形式:
       #ifndef 标识符
                  程序段1
       #else
                  程序段2
       #endif
       如果“标识符”未被定义过,则编译程序段1,否则编译程序段2。
       4.define操作符
       define是预处理操作符,不是指令,所以不能用#开头。使用形式为:define(标识符)。如果括号里的标识符用#define定义过,并且没有用#undef删除,则define(标识符)为非0,否则为0。可以这样使用:
        #if !define(HEAD_H)
        #define HEAD_H
       我们在包含头文件时,有时多次重复包含同一个头文件,比如下面这种情况:
        // main.cpp文件
       #include "file1.h"
       #include "file2.h"
       int main()
       {
              …
       }
       // file1.h文件
       #include "head.h"
        …
       // file2.h文件
       #include "head.h"
        …
       // head.h文件
        ...
       class A
       {
              ...
       }
       ...
       main.cpp包含了file1.h文件,file1.h又包含了head.h文件,main.cpp还包含了file2.h文件,file2.h也包含了head.h文件,那么main.cpp就包含了两次head.h文件,在编译时就会报错,说head.h中的类A重复定义了。这时我们可以在被重复包含的文件head.h中使用条件编译指令,用一个唯一的标识符来标识head.h文件是否已经编译过,如果已经编译过则不会重复编译了。鸡啄米给大家改写下上面的head.h文件:
       // head.h文件
       #ifndef HEAD_H
       #define HEAD_H
       ...
       class A
       {
            ...
       }
       ...
       #endif
       在这个改好的head.h文件中,上来会先判断HEAD_H是否被定义过,如果没有被定义过,则head.h文件还没参与过编译,就编译此文件中的源代码,同时定义HEAD_H,标记head.h文件已经参与过编译。如果HEAD_H已经被定义过,则说明此文件已经参与过编译,编译器会跳过本文件左右内容编译其他部分,类A也不会有重复定义的错误了。
本文来源于鸡啄米博客 http://www.jizhuomi.com/ , 原文地址:http://www.jizhuomi.com/software/70.html
 
1
0
查看评论

有关C++中的多文件组织结构

今天读到了多文件组织结构,感觉对C++的认识又上了一个层次,接下来就谈谈多文件组织结构。 C++中程序的显著特点,有三部分构成,类的定义,类的实现,类的使用(主函数)。 通常一个程序是由多个源程序文件构成,源程序文件又称为编译单元,每个源程序文件可以进行单独编写,编译,再进行连接。 再来说说源...
  • CSDN_LYY
  • CSDN_LYY
  • 2014-12-13 23:12
  • 1700

c++单独编译和c++的多文件组织结构

1.通常当一个程序代码较多较复杂时,我们会ba
  • liuwei271551048
  • liuwei271551048
  • 2014-04-13 14:23
  • 2866

【C++】多文件程序结构

以前写一个C++多文件程序的时候经常为哪些东西应该放在.h文件里,哪些东西应该放在.cpp文件里而疑惑。稍有不慎就搞出一个“error:LNK2005 已经在*.obj中定义”的重复定义错误,就算解决了这个问题自己实际上也还是一知半解。最近去了解了C++多文件程序结构的知识,才搞清楚了这些问题的本质...
  • muxing_csdn
  • muxing_csdn
  • 2016-04-06 20:16
  • 3408

C++学习(四) C++程序的多文件结构

C++语言支持面向对象程序设计,主要体现在类的定义和应用上。一般情况下,一个模块由规范说明和实现两部分组成。规范说明部分描述一个模块与其他模块的接口,而实现部分则是模块的实现细节。模块中的说明部分作为一个单独的文件存放起来,这个文件被称为头文件,其扩展名为“.h”;而实现部分可能由多个扩展名为“.c...
  • feizaoSYUACM
  • feizaoSYUACM
  • 2017-11-28 14:00
  • 387

对C++多文件程序的总结及例程

C++程序设计中常把类声明和成员函数定义分离开来,一个C++程序由3部分组成: (1)类声明头文件(后缀为 .h)。 (2)类实现文件(后缀为 .cpp),它包括类成员函数的定义。 (3)类使用文件(后缀为 .cpp),即主函数文件。 来看看这个简单的题目:找出10个整型数值的最大值...
  • sc2016cs
  • sc2016cs
  • 2016-06-21 19:23
  • 94

C++编译运行多个文件形式的程序

C++编译运行多个文件形式的程序 一.   头文件和源文件的区别: 1.   从技术层面上来说,*.h文件 *.c文件 *.cpp文件没什么区别,里面放的都是C++的源代码。 2.   但从开发习惯来说,大家都遵循一个...
  • CSDN2497242041
  • CSDN2497242041
  • 2015-11-22 22:54
  • 4106

dev-c++怎么运行多个文件

当你写了都个文件想让他们在一起编译运行时,却发现编译器不买账; 这是你需要建一个项目 你可以在这里选择建立一个空白的项目,在项目里面的多个文件可以一同编译运行。
  • wang20142052
  • wang20142052
  • 2016-11-10 19:12
  • 1307

C语言常用的代码组织形式--多文件

对于小型代码而言,可以将所有的文件写到一个源文件中。但是对于一个大的项目工程,代码量极大,如果把所有的源码都放在一个源文件,就会显得代码杂乱,不利于阅读,更不便于代码的修改和维护。这时候我们需要合理的组织代码,可以使用多个文件,把源码归类放到不同的文件中。 程序多文件一般分为两类: 1、头文件(.h...
  • gybshen
  • gybshen
  • 2016-04-26 21:35
  • 2340

Dev-C++:同时编译多个文件

现场:今天编写了多个C++文件,需要同时进行编译,单独用DEV_C++编译后,无效果,不能达到程序的预期 解决方法: 1、DEV-C++中添加一个空白工程 2、点击菜单中“工程”---“添加”选项,在出现的弹出界面中,同时选择需要编译的多个文件 3、再次点
  • AwL_1124
  • AwL_1124
  • 2011-09-06 16:02
  • 3469

C++多文件编译问题

1: 在查找预编译头使用时跳过解决 环境:VS2008 微软官方解释: Visual C++Concepts: Building a C/C++ ProgramCompiler Warning (level 1) C4627Error Message ”: skipped when loo...
  • gexiaobaoHelloWorld
  • gexiaobaoHelloWorld
  • 2012-02-25 12:49
  • 5724
    个人资料
    • 访问:213190次
    • 积分:3569
    • 等级:
    • 排名:第10989名
    • 原创:95篇
    • 转载:193篇
    • 译文:0篇
    • 评论:22条
    博客专栏
    最新评论