原文:https://www.cnblogs.com/ider/archive/2011/06/30/what_is_in_cpp_header_and_implementation_file.html
| ||
头文件(.h) |
| 带inline限定符的全局模板函数的声明和定义 |
| 模板类的定义 模板类成员的声明和定义(定义可以放在类内或者类外,类外不需要写inline) | |
实现文件(.cpp) |
| (无) |
|
详细解释:
头文件
头文件的所有内容,都必须包含在
#ifndef {Filename}
#define {Filename}
//{Content of head file}
#endif
这样才能保证头文件被多个其他文件引用(include)时,内部的数据不会被多次定义而造成错误
inline限定符
在头文件中,可以对函数用inline限定符来告知编译器,这段函数非常的简单,可以直接嵌入到调用定义之处。
当然inline的函数并不一定会被编译器作为inline来实现,如果函数过于复杂,编译器也会拒绝inline。
因此简单说来,代码最好短到只有3-5行的才作为inline。有循环,分支,递归的函数都不要用做inline。
对于在类定义内定义实现的函数,编译器自动当做有inline请求(也是不一定inline的)。因此在下边,我把带有inline限定符的函数成员和写在类定义体内的函数成员统称为“要inline的函数成员”
非模板类型
全局类型
就像前面笼统的话讲的:声明写在.h文件。
对于函数来讲,没有实现体的函数,就相当于是声明;
而对于数据类型(包括基本类型和自定义类型)来说,其声明就需要用extern来修饰。
然后在.cpp文件里定义、实现或初始化这些全局函数和全局变量。
自定义类型
对于自定义类型,包括类(class)和结构体(struct),它们的定义都是放在.h文件中。其成员的声明和定义就比较复杂了,不过看上边的表格,还是比较清晰的。
函数成员
函数成员无论是否带有static限定符,其声明都放在.h文件的类定义内部。
对于要inline的函数成员其定义放在.h文件;其他函数的实现都放在.cpp文件中。
数据成员
数据成员的声明与定义都是放在.h文件的类定义内部。对于数据类型,关键问题是其初始化要放在什么地方进行。
对于只含有static限定符的数据成员,它的初始化要放在.cpp文件中。因为它是所有类对象共有的,因此必须对它做合适的初始化。(静态成员变量)
对于只含有const限定符的数据成员,它的初始化只能在构造函数的初始化列表中完成。因为它是一经初始化就不能重新赋值,因此它也必须进行合适的初始化。
对于既含有static限定符,又含有const限定符的数据成员,它的初始化和定义同时进行。它也是必须进行合适的初始化
对于既没有static限定符,又没有const限定符的数据成员,它的值只针对本对象可以随意修改,因此我们并不在意它的初始化什么时候进行。
示例:
#ifndef HANDCPP_H
#define HANDCPP_H
#include <QWidget>
#include<QDebug>
//全局类型
//函数原型
double * G_function(int x,int y);
//结构体声明
typedef struct student
{
int T_a;
double T_b;
}STU;
//类声明
class HandCPP : public QWidget
{
Q_OBJECT
public:
explicit HandCPP(QWidget *parent = nullptr);
//接口声明
void test(int x,double y);//函数原型
//数据声明
int x;
double y;
//static(静态成员变量)
static double Pi;//在.h中声明,.cpp中具体分配空间
//const关键字
const int MAX;//在构造函数中初始化
//static const(顺序颠倒问题不大)
static const double T;
//所有类型的变量都可以声明为static const
//只是除int类型外,其它的类型都必须要在.cpp中进行定义,只能在.h中进行声明
//但是int类型则可以在.h中进行定义
signals:
public slots:
};
#endif // HANDCPP_H
#include "handcpp.h"
//static(静态成员变量)
double HandCPP::Pi = 3.1415926;//在.h中声明,.cpp中具体分配空间
//const static的初始化
const double HandCPP::T = 6.36;
//全局类型
//全局变量
int G_x = 0;
double X[3] = {0};
const int i = 1;//常规的全局变量,加上const修饰
//全局结构体
STU G_Stu;//局部变量自行在函数中定义即可
//函数原型
double * G_function(int x,int y)
{
X[0] = x*y/0.2;
X[1] = x*y/0.2;
X[2] = x*y/0.2;
return X;
}
HandCPP::HandCPP(QWidget *parent) :
QWidget(parent),
MAX(10)
{
qDebug()<<"T:"<<T;
qDebug()<<"MAX:"<<MAX;
}