欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++ - 工程中头文件的定义

程序员文章站 2022-03-31 10:09:50
头文件 头文件大家都明白,里面存放了我们需要使用的『工具』,也是我们在使用某个类库的时候,需要include进来的内容。 定义头文件 定义头文件需要注意以下内容: 要防止被...

头文件

头文件大家都明白,里面存放了我们需要使用的『工具』,也是我们在使用某个类库的时候,需要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.h

Main.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 
#include 
#include 

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 
#include 
#include 

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文件。