本文转自:http://blog.csdn.net/forevertali/article/details/4370602

 

animal.h

//在头文件中包含类的定义及类成员函数的声明

class animal

{

public:

animal();

~animal();

void eat();

void sleep();

virtual void breathe();

};

animal.cpp

//在源文件中包含类中成员函数的实现

#include "animal.h"         //因为在编译animal.cpp时,编译器不知道animal到底

是什么,所以要包含animal.h,这样,编译器就知道animal

是一种类的类型

#include <iostream.h>       //在包含头文件时,<>和""有什么区别?<>和""表示编译器

在搜索头文件时的顺序不同,<>表示从系统目录下开始搜索,

然后再搜索PATH环境变量所列出的目录,不搜索当前目录;

""是表示先从当前目录搜索,然后是系统目录和PATH环境

变量所列出的目录。所以如果我们知道头文件在系统目录下

就可以直接用<>,这样可以加快搜索速度

animal::animal()            //::叫做作用域标识符,用于指明一个函数属于哪个类或一

个数据成员属于哪个类。::前面如果不跟类名,表示是全局

{                           函数(即非成员函数)或全局数据

}

animal::~animal()

{

}

void animal::eat()          //注意:虽然我们在函数体中什么也没写,但仍然是实现了

这个函数

{

}

void animal::sleep()

{

}

void animal::breathe()      //注意,在头文件(.h文件)中加了virtual后,在源文

件(.cpp文件)中就不必再加virtual了

{

cout<<"animal breathe"<<endl;

}

fish.h

#include "animal.h"         //因fish类从animal类继承而来,要让编译器知道

animal是一种类的类型,就要包含animal.h头文件

class fish:public animal

{

public:

void breathe();

};

fish.cpp

#include "fish.h"

#include <iostream.h>

void fish::breathe()

{

cout<<"fish bubble"<<endl;

}

EX10.cpp

#include "animal.h"

#include "fish.h"

void fn(animal *pAn)

{

pAn->breathe();

}

void main()

{

animal *pAn;

fish fh;

pAn=&fh;

fn(pAn);

}

现在我们就可以按下键盘上的F7功能键编译整个工程了,编译结果如下:

为什么会出现类重复定义的错误呢?请读者仔细查看EX10.cpp文件,在这个文件中包含了animal.h和fish.h这两个头文件。当编译器编译EX10.cpp文件时,因为在文件中包含了animal.h头文件,编译器展开这个头文件,知道animal这个类定义了,接着展开fish.h头文件,而在fish.h头文件中也包含了animal.h,再次展开animal.h,于是animal这个类就重复定义了。

读者可以测试一下,如果我们多次包含iostream.h这个头文件,也不会出现上面的错误。要解决头文件重复包含的问题,可以使用条件预处理指令。修改后的头文件如下:

animal.h

#ifndef ANIMAL_H_H      //我们一般用#define定义一个宏,是为了在程序中使用,使程

                            序更加简洁,维护更加方便,然而在此处,我们只是为了判断

#define ANIMAL_H_H      ANIMAL_H_H是否定义,以此来避免类重复定义,因此我们没有为

                        其定义某个具体的值。在选择宏名时,要选用一些不常用的名字,

class animal            因为我们的程序经常会跟别人写的程序集成,如果选用一个很常用

的名字(例如:X),有可能会造成一些不必要的错误

{

public:

animal();

~animal();

void eat();

void sleep();

virtual void breathe();

};

#endif

fish.h

#include "animal.h"

#ifndef FISH_H_H

#define FISH_H_H

class fish:public animal

{

public:

void breathe();

};

#endif

我们再看EX10.cpp的编译过程。当编译器展开animal.h头文件时,条件预处理指令判断ANIMAL_H_H没有定义,于是就定义它,然后继续执行,定义了animal这个类;接着展开fish.h头文件,而在fish.h头文件中也包含了animal.h,再次展开animal.h,这个时候条件预处理指令发现ANIMAL_H_H已经定义,于是跳转到#endif,执行结束。

通过分析,我们发现在这次的编译过程中,animal这个类只定义了一次。

[转]VC++的类头文件的更多相关文章

  1. 实现C++模板类头文件和实现文件分离的方法

    如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer(第四版)>>里的观点:1)标准C++为编译模板代码定义了两种模型:“包含”模型和“ ...

  2. C++模板类头文件和实现文件分离

    http://www.cnblogs.com/lvdongjie/p/4288373.html 如何实现C++模板类头文件和实现文件分离,这个问题和编译器有关. 引用<<C++primer ...

  3. 1.svn 彻底clear时,注意代码备份 2.借助vc助手加头文件

    1.svn 彻底clear时,注意代码备份 2.不小心彻底clear可以在回收站找到 3.借助vc助手加头文件

  4. vc使用jsoncpp头文件冲突问题

    编译时出现 1>d:\program files (x86)\microsoft visual studio 9.0\vc\include\xdebug(32) : warning C4229: ...

  5. VC++中的头文件包含问题

    在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已 ...

  6. 【QT相关】类头文件解读、QT编辑模式、读取text文本

    Wizard产生的头文件类包含了必须的#include文件.构造函数.析构函数和UI对象: #include <QMainWindow> namespace Ui {class Notep ...

  7. Qt - 错误总结 - 在自定义类头文件中添加Q_OBJECT 编译时报错(undefined reference to ‘vtable for xxThread)

    错误提示:在添加的QThread子类头文件添加Q_OBJECT时,编译程序,出现"undefined reference to 'vtable for xxThread'"错误提示 ...

  8. VC中添加头文件以及库

    原文:http://blog.csdn.net/lwb102063/article/details/52068389   附加头文件包含 VC6.0中: VC6.0默认include包含路径:Tool ...

  9. vc++中 .H 头文件引用的顺序与符号关系

    在使用 #include "math.h"  和 #include <math.h>时,引号 与尖括号的区别如下 此时math.h_1 在工程文件中 math.h_2 ...

随机推荐

  1. 20170301 Excel 导出函数XXL_SIMPLE_API

    * XMPLT_V-COL_NO = . * XMPLT_V-COL_NAME = '物料号码'. * APPEND XMPLT_V. * * XMPLT_V-COL_NO = . * XMPLT_V ...

  2. XMU C语言程序设计实践(3)

    问题描述: 以一个n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论. 对于本问题需用栈实现“穷举求解”算法,即:从 ...

  3. 谈谈Paxos一致性算法和一致性这个名词

    转自:http://www.cnblogs.com/esingchan/p/3917718.html 维基的简介:Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的& ...

  4. 简易SQL语句

    /*创建 模式 为用户 User1*/ CREATE SCHEMA test authorization User1; CREATE SCHEMA test USER User1; CREATE TA ...

  5. http的安全方法和幂等性

    最近在研究http,看到http的安全方法和幂等性部分,不太明白,尤其是"post方法是非幂等的"不理解,进过查资料,找到以下两篇有价值的文章,特转过来! 理解HTTP幂等性 转自 ...

  6. ubuntu IP 扫描

    /******************************************************************************* * ubuntu IP 扫描 * 说明 ...

  7. 详述IntelliJ IDEA插件的安装及使用方法(图解)

    intellij idea是一款非常优秀的软件开发工具,它拥有这强大的插件体系,可以帮助开发者完成很多重量级的功能.今天,我们来学习一下如何安装和卸载intellij idea的插件. Intelli ...

  8. BZOJ2217:Lollipop

    题意 给定一个由1和2组成的序列,多次询问是否存在一个区间满足区间和=x 分析 结论:假如存在一个子串和为x,那么一定存在一个前缀,和为x或x+1 证明:可以认为原串是由和为x的串在开头和结尾添加若干 ...

  9. bzoj 2560: 串珠子【状压dp】

    正难则反,设g[s]为集合s不一定联通的方案数,这个很好求,把边数+1乘起来即可,f[s]为s一定联通的方案数 f考虑容斥,就是g[s]-Σf[nw]*g[s^nw],nw是s的子集,这样就减掉了不联 ...

  10. Hello world——程序员的第一篇代码

    Hello world 是和A+B问题并驾齐驱的一道题,也是当世的经典题之一. 题目: 输出“Hello world”    样例输入 样例输出    Hello world Hello world ...