今天再看二叉树的知识,看着看着就看到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
小结:这些小问题当自己没遇到的绝得都是小问题没什么,但是当真正用的时候发现这也错那也错。很是郁闷,因此每每遇到这种小问题时不如做个笔记,放在网上最好不但自己方便查阅。也方便刚学的人参考,利人利己,何乐而不为!