今天再看二叉树的知识,看着看着就看到C/C++的头文件及头文件重复定义这一块去了。以前就看到过这个问题,但是自己一直没有用到这方面的东西,今天遇到就顺便总结一下,等以后忘了再回来看看。

  首先明确一点C/C++头文件是要来干什么的?(http://baike.baidu.com/link?url=lMbCZqCAsBJ_rhifA82koGGjoJmbZUy1tTPNPzertEc7nxNr71Xqfm63GEuqA8Ze

  头文件的作用有三:
          1、C\C++采用源文件单独编译为object文件,最后有链接器链接object文件成为可执行文件头文件解决了彼源文件中变量和函数在此源文件中引用。
          2、头文件中的函数接口和全局变量占位符的作用和参数类型与表达式匹配的合法行检测的作用,早期的C编译器不具有后者的功能。
          3、便于一二进制的形式发行类库,因此源码实现的细节。

  一般用到的第三条比较多一点,就是在*.h的头文件中定义类,而不具体实现类的细节。把类的细节实现放在*.cpp文件中来实现。这样实现定义和实现的细节分开,使程序的结构更加清晰明了。

  举个例子:

      /Animal.h

      class Animal
     {
        private:
             char Gender;
             int Age;
        public:
             Animal(char gen,int age);
             Animal();
             char GetGender();
             int GetAge();
      };

  具体实现在Animal.cpp文件中实现

//这里必须包含定义的头文件

#include "Animal.h"

Animal::Animal()
{
 Gender='M';
 Age=0;
}

Animal::Animal(char gen,int age)
{
 Gender=gen;
 Age=age;
}

char Animal::GetGender()
{
 return Gender;
}

int Animal::GetAge()
{
 return Age;
}

这样类体的定义和实现就分开了。只需要在另一个cpp文件中定义一个主函数就可以直接用自己定义好说的类了,注意不要忘记包含头文件。

举个例子:

#include <iostream>
#include "Animal.h"
using namespace std;

int main()
{
 Animal a('F',14),s;
 cout<<a.GetAge()<<endl;
 cout<<a.GetGender()<<endl;

return 0;
}

这里涉及一个类,下面再来定义一个Bird类来讲讲头文件重复定义的问题:

同样先定义头文件:Bird.h

#include "Animal.h"
class Bird
{
private:
 Animal Property;
 bool Fly;
public:
 Bird();
 Bird(bool fly,Animal an);
 void SetFly();
 void SetNoFly();
 bool GetFly();
 Animal GetAnimalProperty();
};

注意这是由于该头文件中包含了#include "Animal.h"头文件,当再次在其他cpp文件中包含Bird.h和#include "Animal.h"时就会出现头文件重复定义。

编译时具体的错误信息:

Compiling...
RepeatHeadFile.cpp
e:\acm\acm 程序设计实战\repeatheadfile\animal.h(4) : error C2011: 'Animal' : 'class' type redefinition
Animal.cpp
Bird.cpp
执行 cl.exe 时出错.

Bird.cpp实现

#include "Bird.h"
Bird::Bird()
{
 Property=Animal();
 Fly=true;
}
Bird::Bird(bool fly,Animal an)
{
 Fly=fly;
 Property=an;
}

void Bird::SetFly()
{
 Fly=true;
}

void Bird::SetNoFly()
{
 Fly=false;
}

bool Bird::GetFly()
{
 return Fly;
}

Animal Bird::GetAnimalProperty()
{
 return Property;
}

解决办法是c/c++给出的预编译命令

#ifndef

#define

//头文件定义

...........

#endif

重新贴一下有预编译命令的头文件定义代码:Animal.h

#ifndef ANIMAL_H_H
#define ANIMAL_H_H
class Animal
{
private:
 char Gender;
 int Age;
public:
 Animal(char gen,int age);
 Animal();
 char GetGender();
 int GetAge();
};
#endif

Bird.h

#include "Animal.h"
#ifndef BIRD_H_H
#define BIRD_H_H
class Bird
{
private:
 Animal Property;
 bool Fly;
public:
 Bird();
 Bird(bool fly,Animal an);
 void SetFly();
 void SetNoFly();
 bool GetFly();
 Animal GetAnimalProperty();
};
#endif

小结:这些小问题当自己没遇到的绝得都是小问题没什么,但是当真正用的时候发现这也错那也错。很是郁闷,因此每每遇到这种小问题时不如做个笔记,放在网上最好不但自己方便查阅。也方便刚学的人参考,利人利己,何乐而不为!

自定义C/C++头文件以及头文件重复定义解决的更多相关文章

  1. keil C51中建立多文件时,变量重复定义的解决

    c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下. 对于比较小的程序,一般只有一个c文件和一个头文件,全局变量 ...

  2. larave5.6 引入自定义函数库时,报错不能重复定义

    方法一:使用function_exists判断 方法二:使用命名空间 namespace test; function test(){ echo 'test/test'; } namespace te ...

  3. C++中的头文件(.h)和源文件(.cpp)都应该写什么?

    头文件(.h):写定义和声明写类的声明(包括类里面的成员和方法的声明).函数原型.#define常数等,但是一般来说不写具体的实现.注意: 1.在写头文件的时候需要注意,在开头和结尾处必须按照如下样式 ...

  4. C++的头文件和实现文件分别写什么

    在C++编程过程中,随着项目的越来越大,代码也会越来越多,并且难以管理和分析.于是,在C++中就要分出了头(.h)文件和实现(.cpp)文件,并且也有了Package的概念. 对于以C起步,C#作为& ...

  5. windows下使用gcc完成头文件和目标文件编译

    环境要求 安装了gcc win+r然后输入cmd , dos界面输入 gcc -v 查看有没有安装gcc 进入正题 新建 text.c文件键入如下代码: #include <stdio.h> ...

  6. Objective-C声明在头文件和实现文件中的区别

    Objective-C声明在头文件和实现文件中的区别 转自codecloud(有整理) 调试程序的时候,突然想到这个问题,百度一下发现有不少这方面的问答,粗略总结一下: 属性写在.h文件中和在.m文件 ...

  7. C中头文件在cpp文件中引用和.h文件引用

    1.编译器会单独编译每个cpp文件.头文件会复制到cpp文件中. 2.有时会遇到这样的一个问题a.cpp要调用b.cpp中的函数,而b.cpp又要调用a.cpp中的函数.这就牵扯到相互调用.这时如果我 ...

  8. C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?

    C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? 这个feature叫做Export Template,即外名模板,它的作用在于使得模板代码可依照C/C++语言习惯,将模板声明和实现 ...

  9. .h头文件和.c文件的作用和区别

    .h头文件和.c文件的作用和区别 在小工程中,.h的作用没有得到充分的使用,在大工程中才能充分体现出.h文件的作用. .h和.c文件都是代码.头文件好处有: 一:头文件便于共享,只需要添加一句“inc ...

随机推荐

  1. RNN 入门教程 Part 4 – 实现 RNN-LSTM 和 GRU 模型

    转载 - Recurrent Neural Network Tutorial, Part 4 – Implementing a GRU/LSTM RNN with Python and Theano ...

  2. bootstrap学习总结-05 常用标签3

    1 单选框,多选框 1)单选框 单选框(radio)用于从多个选项中只选择一个.设置了 disabled 属性的单选或多选框都能被赋予合适的样式.对于和多选或单选框联合使用的 <label> ...

  3. Mysql配置项的简单优化

    preface 众所周知,Mysql已经成为广泛使用的开源数据库了,so 公司阿里云的数据库为Mysql,在最开始的时候是直接yum安装,配置项都是默认的,没有任何调整,这次有时间就参考各路大神的资料 ...

  4. sudo和rpm命令

    sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如halt,reboot,su等等.这样不仅减少了root用户的登录 和管理时间,同样也提高了安全 ...

  5. uC/OS-II内存(OS_mem)块

    /*************************************************************************************************** ...

  6. CentOS6.5 安装Sphinx 配置MySQL数据源

      前提安装完mysql,并创建测试表和数据 DROP TABLE IF EXISTS `documents`; CREATE TABLE IF NOT EXISTS `documents` ( `i ...

  7. 用js实现QQ自定义在线图片

    用JS实现,具体步骤如下: 1) 申请代码 <a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin ...

  8. bash: ifconfig: command not found解决方法

    1.问题: #ifconfig bash: ifconfig: command not found 2.原因:非root用户的path中没有/sbin/ifconfig ,其它的命令也可以出现这种情况 ...

  9. 解决umount.nfs: /data: device is busy 问题

    有时候我们需要umount某个挂载目录时会遇到如下问题: [root@localhost /]# umount /data/ umount.nfs: /data: device is busy 通过这 ...

  10. Python之路【第十一篇续】前端初识之CSS

    css解释 css样式: css是英文Cascading Style Sheets的缩写,称为层叠样式表,用于对页面进行美化,CSS的可以使页面更加的美观.基本上所有的html页面都或多或少的使用cs ...