c++ include .h .cpp 的区别

背景说明

在面向对象编程的过程中,为了结构清晰,通常将不同的类定义在不同的文件里
使用时通过include .h文件即可,不用include .cpp
正常情况下,定义一个类,将声明写在.h文件中,将实现写在.cpp文件中,.cpp文件中include .h文件即可
但是,我这个类不是通过IDE创建的,而是我自己新建文件,自己写出来的,其实这里就是问题所在

.h文件
#pragma once

class duoxiangshi
{
private:
    int a[100]={0};
    int maxexponent;
public:
    duoxiangshi(int *p,int maxexponent);
    ~duoxiangshi();
    void printdxs();
    friend duoxiangshi dxs_minus(duoxiangshi dxs1,duoxiangshi dxs2);
};
.cpp文件
#include "duoxiangshi.h"
#include <iostream>
using namespace std;

duoxiangshi::duoxiangshi(int *p=NULL,int maxexponent=0)
{
    this->maxexponent=maxexponent;
    if(p!=NULL)
    {
        for(int i=0;i<=maxexponent;i++)
        {
            a[i]=p[i];
        }
    }
}
void duoxiangshi::printdxs()
{
    if(a[0]!=0)
        cout<<1<<'+';
    for(int i=1;i<maxexponent;i++)
    {
        if(a[i]!=0)
        cout<<"x^"<<i<<'+';
    }
    if(a[maxexponent]!=0)
        cout<<"x^"<<maxexponent<<endl;
}

duoxiangshi::~duoxiangshi(){}

duoxiangshi dxs_minus(duoxiangshi dxs1,duoxiangshi dxs2)
{
    duoxiangshi temp=duoxiangshi();
    int maxexpo=dxs1.maxexponent;
    //dxs1-dxs2
    for(int i=maxexpo;i>=0;i--)
    {
        temp.a[i]=dxs1.a[i]-dxs2.a[i];
        if(temp.a[i]<0)
            temp.a[i]*=-1;
    }
    for(int i=maxexpo;i>=0;i--)
    {
        if(temp.a[i]==0)
        {
            --maxexpo;
        }else
        {
            break;
        }
    }
    temp.maxexponent=maxexpo;
    return temp;
}

但是这次在main函数所在文件开头include .h 文件却报错,未定义之类的错误
后来试了一下include .cpp文件,成功运行
不难想到,IDE在创建项目的时候,会有额外的文件记录项目的组成和依赖关系等信息,以方便编译运行
比如vs就是利用.sln(solution)解决方案文件做到这点的,当然里面还有其他信息

SLN ( own's the following details):

    * A list of the projects that are to be loaded into Visual Studio 2005
    * A list of project dependencies
    * Microsoft Visual SourceSafe information
    * A list of add-ins that are available 
以下就当作在vs环境下创建项目

该类是我自己创建文件并编写的,没有使用IDE创建类的接口,因此.sln的文件没有记录我创建的类文件的信息
仔细回想一下,include 对应的.h文件而不用include .cpp文件就可以运行确实需要额外的信息
编译器可以自动找到对应的.cpp实现文件将其链接编译

分析下解决方案的作用

通过IDE创建类会自动将.h .cpp文件加入解决方案,并且一一对应,链接编译时读取解决方案
遇到.h文件声明,将对应的.cpp文件也进行处理
而不在解决方案内的类文件.h .cpp则不会被编译器识别
所以需要利用#include命令将.cpp文件(定义实现)包含进啦(相当于复制.cpp文件的内容放在这里)
只是#include .h 文件仅仅将声明加入进来,编译器找不到.cpp中的定义实现
所以才会出现开头的错误
因此,开头引入.h文件,在文件的最后#include .cpp文件同样可以运行,这也证明了#include .cpp就是复制内容加入进来
这个时候应该将
#include .h 文件理解为声明
#include .cpp 文件理解为实现(代码复制拷贝)
平时写代码时也是这样,调用某个函数,前面要么把该函数定义了,要么声明一下,然后在后面定义
在自己创建类文件(没有加入解决方案)的时候应该在开头(函数调用前)#include .cpp 把定义加入进来
或者在开头(函数调用前)加入声明#include .h,在后面加入定义#include .cpp

posted @ 2020-10-20 15:23  ecnu_lxz  阅读(2653)  评论(0编辑  收藏  举报