头文件
头文件大家都明白,里面存放了我们需要使用的『工具』,也是我们在使用某个类库的时候,需要include进来的内容。
定义头文件
定义头文件需要注意以下内容:
- 要防止被重复
include
- 在某些情况下只写声明(declare),不写定义(define)
首先如何防止重复include
呢?其实很简单,就是加上:
#ifndef
#define SYMBOL
#endif
例如如下我定义了一个头文件,名字叫做Header.h
,里面的内容可以写成如下的样子:
//
// Header.h
// HihocoderTest
//
// Created by Alps on 16/6/23.
// Copyright © 2016年 chen. All rights reserved.
//
#ifndef Header_h
#define Header_h
//write code here
#endif /* Header_h */
这样就可以防止被重复include
了。
那么是不是一定没有问题了呢?
不是的!
假如Header.h里面写了除了declare还有define的内容例如:
//
// Header.h
// HihocoderTest
//
// Created by Alps on 16/6/23.
// Copyright © 2016年 chen. All rights reserved.
//
#ifndef Header_h
#define Header_h
//write code here
int add(){
return 0;
} //declare and define
#endif /* Header_h */
假如出现一种情况:
三个文件:
Header.h
Main.cpp
Test.h其中
Test.h
#include Header.hMain.cpp
#include Header.h
#include Test.h
这种情况,在编译链接的阶段,会报错的,redeclared的错误。
但是如果只有声明的话,是不会有问题的。所以这就是为什么我们平时在添加这些库文件的头文件,没有遇到redclared的问题。
所以可以在头文件里这样写:
//
// Header.h
// HihocoderTest
//
// Created by Alps on 16/6/23.
// Copyright © 2016年 chen. All rights reserved.
//
#ifndef Header_h
#define Header_h
//write code here
int add(); //declare without define
int add(); // redeclare is also ok
#endif /* Header_h */
即使写两个,也不会有问题。
特殊情况
在我们定义类的时候,我们一般的定义形式是,把类和类方法的声明和类方法的定义分开来写:
正常定义类
例如类User
文件:
User.h
User.cpp
//
// User.h
// HihocoderTest
//
// Created by Alps on 16/7/24.
// Copyright © 2016年 chen. All rights reserved.
//
#ifndef User_h
#define User_h
#include <stdio.h>
#include <string>
#include <cstring>
class User{
private:
std::string name;
std::string sex;
public:
User();
User(std::string n, std::string s);
std::string getName();
void setName(std::string name);
};
#endif /* User_h */
而User.cpp文件:
//
// User.cpp
// HihocoderTest
//
// Created by Alps on 16/7/24.
// Copyright © 2016年 chen. All rights reserved.
//
#include "User.hpp"
User::User(std::string n, std::string s):name(n), sex(s){}
std::string User::getName(){
return this->name;
}
void User::setName(std::string name){
this->name = name;
}
特殊写法
现在新的标准里,在建立头文件的时候,后缀名是:hpp
了,其实是为了方便把类的声明和定义放在一起了。
写法如下:
//
// User.hpp
// HihocoderTest
//
// Created by Alps on 16/7/24.
// Copyright © 2016年 chen. All rights reserved.
//
#ifndef User_hpp
#define User_hpp
#include <stdio.h>
#include <string>
#include <cstring>
class User{
private:
std::string name;
std::string sex;
public:
User();
User(std::string n, std::string s);
std::string getName();
void setName(std::string name);
};
User::User(std::string n, std::string s):name(n), sex(s){}
std::string User::getName(){
return this->name;
}
void User::setName(std::string name){
this->name = name;
}
#endif /* User_hpp */
这样不是出现了我上面说的,会出现在链接阶段的redeclare的情况么 ?
其实不会的,是因为这个是类,实际上,所有的这些都算是类的声明而已,因为类是不会在编译阶段就知道占用内存大小的,所以这个和普通的函数声明一样,这样就不会出现redeclare了。
疑问
那为什么int a; int a;
这种我只是声明了,没有定义也会报错呢? 是因为基本类型是在认为声明的时候就定义了。所以不能重复声明的。
总结
总结起来就是,正常情况一般还是把声明和定义分开放,这样可以让工程的结构更为清晰。
类是可以放在一起的。也就是hpp
文件。