精华内容
下载资源
问答
  • PictureEx的.h文件和.cpp文件,PictureEx图片显示类支持以下格式的图片: GIF (including animated GIF87a and GIF89a), JPEG, BMP, WMF, ICO, CUR等。
  • .h文件和.cpp文件组织结构

    千次阅读 2014-12-02 17:46:47
    .h文件一般包含在.cpp文件中,.h文件中多为变量类的声明,而.cpp文件才是变量类中函数的真正定义。 #include      哈,这个文件既不是 .c 也不是 .h ,那我们能不能不用它,改用 iostream.h ?一般 来说只是...

    1、包含关系:

    .h文件一般包含在.cpp文件中,.h文件中多为变量和类的声明,而.cpp文件才是变量和类中函数的真正定义。

    但是#include <iostream> 这个文件既不是.c也不是.h,那我们能不能不用它,改用iostream.h?一般来说只是为了使用cout这种对象是可以的。但意义上有差别,iostream和iostream.h是不一样的,一个是模板库,一个是C++库头文件。这里顺便提起一下以前的一件事,我刚进入上上家公司的时候,头要我们写个类模板,于是我就跟写一般的类一样把它分为两个文件,一个.h,一个.cpp,一个放定义,一个放实现。你们认为我的做法有问题么?写过模板的人都应该知道,这样是不行的,因为C++中的实现是针对类的实现,而不是针对模板的实现,分开写会导致连接时候找不到实现的。因此必须将模板的“定义”与“实现”写在同一个文件中,那这个文件究竟叫“.h”好呢还是“.cpp”好呢?都不好,它既不是类的定义也不是类的实现,它是模板,模板就是模板,那干脆就不用文件扩展名,STL就怎么干的,That’s OK!

    摘自:http://wenku.baidu.com/link?url=VxeYRH5Lf3cgBwCYO6vRnYIsRDr5UynV8WwFwlg5-39puJklkkf-UndQ40PDOpwl-_AHmmzXbGc6r231ZKMWQcTUjpVmUN2hPfCkddCTaii

    2、基类中有派生类的指针,或者A类中有B类指针,B类中有A类指针

    基类为CBase,子类有CDerivedA,CDerivedB,这倒没什么,但CBase中竟然有这种函数:

    class CBase
    {     
    	//…… 
    	virtual CDerivedA* GetA();
    	virtual CDerivedB* GetB();
    };

    DerivedA.h和DerivedB.h中需要include Base.h,而CBase竟然也用到了它的子类……那根据哪里用到就哪里包含的法则,Base.h是不是也要include DerivedA.h和DerivedB.h?这岂不是形成了“互相包含”?是的,如果出现了这种互相包含,VC++就会给出编译警告。当然如果你做了“反重复包含” 的工作,编译警告就不会出现,也不会出现“重复定义”,而取而代之的是“未定义”,程序还是通不过的。比如下面这个简单的例子:

    //基类 Base.h 
    #ifndef __BASE_H__#define __BASE_H__   
    #include"DerivedA.h"   
    class CBase
    { 
    public:     
    	CBase();    
    	~CBase();     
    	virtual CDerivedA*GetA(){return NULL;}
    };
    #endif
    //子类 DerivedA.h
    #ifndef __DERIVED_A_H__
    #define __DERIVED_A_H__
    #include"Base.h" 
    classCDerivedA:public CBase
    {
    public:
    	CDerivedA();
    	~CDerivedA();
    	virtual CDerivedA* GetA()
    	{return this;}
    }; 
    #endif

    编译出现的错误大致如下,但并非一定,甚至每次都有可能不同,这和编译的顺序有关系:

    error C2143:syntax error : missing ';' before '*' 

    error C2433:'CDerivedA' : 'virtual' not permitted on data declarations

    error C2501:'CDerivedA' : missing storage-class or type specifiers

    error C2501:'GetA' : missing storage-class or type specifiers   

    总之出现了这种基类“需要”子类的情况的话,就不能这样include了。取而代之的是使用一个类的声明:在Base.h中把“#include "DerivedA.h"”去掉,用“class CDerivedA;”取代它。这样编译就没有问题了。   

    OK OK,可能你又有问题了,如果基类中的函数不是“virtual CDerivedA* GetA()”,而是“virtual CDerivedA GetA()”,那怎么又通不过了?哇哈哈……老兄,你别扯了,我保证你找遍全世界的高手,也没有人能解决这个问题的,因为它逻辑上已经错误了,父在诞生的时候需要子,而父没诞生,哪来的子?又一个典型的鸡生蛋,蛋生鸡的问题。至于指针为什么就可以,因为指针在Win32中归根到底只是一个long型,它并不需要理解CDerivedA究竟何方神圣,只需要连接的时候找到就行了,反过来如果不是指针,CBase就要尝试寻找CDerivedA并生成实例,这可能吗?

    注意:在派生类从基类继承时,此时必须要有基类的完整声明,不能只有前向声明,即class Base;这样是不能通过编译的。如下代码:注意是错的

    #include<iostream>
    using namespace std;
    
    class A;
    class B:public A
    {
    	
    };
    
    class A
    {
    	int m;
    public:
    	void fun();
    };
    
    int main()
    {
    	A aa;
    	B bb;
    
    	system("pause");
    	return 0;
    }
    输出的错误提示为:error C2504: 'A' : base class undefined

    3、注意基类中有派生类时的构造函数

    //a.h
    #ifndef _AAA_
    #define _AAA_
    class Derived;
    class Base
    {
    protected:
    	Derived *p;
    public:
    	Base(){};
    	Base(Derived &d);
    	~Base(){}
    	void fun();
    };
    #endif
    
    //a.cpp
    #include"a.h"
    #include"b.h"
    Base::Base(Derived &d)
    {
    	p=&d;
    }
    void Base::fun()
    {
    	//可以调用Derived类中的函数,因为b.h中有函数声明
    	p->getA();
    }
    
    //b.h
    #ifndef _BBB_
    #define _BBB_
    #include"a.h"
    class Derived:public Base
    {
    	int a;
    	int b;
    public:
    	Derived(){}
    	Derived(int _a,int _b);
    	~Derived(){}
    	int getA();
    };
    #endif
    
    //b.cpp
    #include"b.h"
    #include<iostream>
    Derived::Derived(int _a,int _b)
    {
    	a=_a;
    	b=_b;
    	p=new Derived();
    	std::cout<<"111"<<std::endl;
    }
    
    int Derived::getA()
    {
    	std::cout<<a<<std::endl;
    	return a;
    }
    
    //test.cpp
    #include<iostream>
    #include"a.h"
    #include"b.h"
    using namespace std;
    
    int main()
    {
    	Base a;
    	Derived d(1,2);
    	Base b(d);
    	b.fun();
    
    	system("pause");
    	return 0;
    }
    
    如果基类只有一个构造函数,那么这个构造函数必须有缺省参数,而且只能复制为0,这样在构造派生类对象时,调用基类的构造函数,就不会存在再调用派生类构造函数的无限循环中了,即派生类中绝不能出现p=new Derived();因为这样将回到先有鸡还是先有蛋的问题上了。

    3、如果不用头文件,而直接定义基类和派生类又会有问题:如下是人和狗的问题,即Man类中有Dogs类的指针,表示人拥有的狗,而Dogs类中也有Man的指针,表示狗属于的人。这样如果先写Dogs类,就需要前向声明Man类,但是在Dogs类中的void printmsg();函数需要调用Man类中的char *getName()来得到名字,但是此时只有Man进行了前向声明,无法得知char *getName()函数的任何信息,因此就需要将void printmsg();函数放到char *getName()函数的声明或者定义之后。

    #include <iostream>
    using namespace std;
    
    class Man;
    class Dogs
    {
    public:
    	char name[20];
    	Man *master;
    	Dogs(char *name,Man *m):master(m)
    	{
    		strcpy(this->name,name);
    	}
    	Dogs(char *name)
    	{
    		strcpy(this->name,name);
    		master=NULL;
    	}
    	void addMasterMsg(Man &m)
    	{
    		master=&m;
    	}
    	//在这里不能定义,因为用到了Man类中的函数,而Man类在前面只是声明了类,
    	//并没有声明函数,因此不能用Man类中的函数
    	void printmsg();
    };
    
    
    class Man
    {
    	char name[20];
    public:
    	Dogs *dogs[10];
    	Man(char *name)
    	{
    		strcpy(this->name,name);
    		for(int i=0;i<10;i++)
    		{
    			dogs[i]=NULL;
    		}
    	}
    	void addDog(Dogs *dog,int i)
    	{
    		dogs[i-1]=dog;
    	}
    	void printmes()
    	{
    		cout<<name<<"的狗有:"<<endl;
    		for(int i=0;i<10;i++)
    		{
    			if(dogs[i])
    				cout<<"第"<<i<<"只狗名字是:"<<dogs[i]->name<<endl;
    			
    		}
    	}
    	char *getName()
    	{
    		return name;
    	}
    };
    
    void Dogs::printmsg()
    {
    	cout<<name<<"是"<<master->getName()<<"的狗"<<endl;
    }
    
    int main()
    {
    	Man m1("zhangsan");
    	cout<<m1.getName()<<endl;
    	Dogs d1=("dog1");
    	d1.addMasterMsg(m1);
    	m1.addDog(&d1,1);
    
    //	Dogs d2=("dog2",&m1);不知道为什么这样做构造函数不行,而且构造函数用初始化列表也不行。
    	//只能如上,用add函数增加
    //此处应该用Dogs d2=Dogs(“dog2”,&m1);才对,这样用的是默认的拷贝构造函数,临时构造一个对象,
    //完成拷贝,或者Dogs d2(“dog2”,&m1);也可以,千万不能用上面所示的错误的代码。赋值根本就不合//语法!!!
    	Dogs d3=Dogs("dog3",&m1);
    	Dogs d4("dog4",&m1);
    
    	m1.printmes();
    	d1.printmsg();
    
    	cout<<sizeof(Man)<<"	"<<sizeof(Dogs)<<endl;
    
    	system("pause");
    	return 0;
    }
    
    在这里如果有多个函数需要调用不同类之间的函数,就需要不断的进行声明,或者进行顺序化的定义,防止一个函数定义时,其调用的函数还没有声明。但是如果利用.h和.c文件来组织程序,就能够避免混乱的程序代码。此时,只需要分别定义Dogs.h实现Dogs类声明,当然要前向声明class Man,Man.h实现Man类声明,当然也要前向声明classDogs,或者包含Dogs.h文件。然后在定义Dogs.cpp和Man.cpp都包含Dogs.h和Man.h即可。完美的解决了上面的问题,而且思路很清晰,结构也很明了。

    4、注意externstatic关键字

    extern表示声明变量,一般用在.h文件中,而定义放在.cpp文件中,static关键字其实是为了屏蔽extern的声明,或者说是当前.cpp文件中的全局变量,但是不会被其他文件所用到。而且当前.cpp文件中有和extern变量重名,在此cpp中,用static变量。

    //a.h
    #ifndef _AAA_
    #define _AAA_
    extern int globalVariant;
    #endif
    
    //a.cpp
    #include"a.h"
    int globalVariant=10;
    
    //test.cpp
    #include<iostream>
    #include"a.h"
    using namespace std;
    
    static int globalVariant=100;
    
    int main()
    {
    	cout<<globalVariant<<endl;
    	globalVariant=3;
    	cout<<globalVariant<<endl;
    
    	system("pause");
    	return 0;
    }
    

    5、.cpp文件是需要编译的,但是.h文件是不需要进行编译的,如果包含.h文件就能够减少编译的时间。

    如果把函数的定义写在.h文件中,例如把fun1()写在了a.h中,而在b.cpp中包含了a.h,在test.cpp中也包含了a.h,那么此时就会报错,说函数重复定义了,因此把声明写在.h文件中,把定义写在.cpp文件中是比较好的办法。

    //a.h
    #ifndef _AAA_
    #define _AAA_
    int fun1()
    {
    	int a=1;
    	int b=2;
    	return a;
    }
    #endif
    
    //b.cpp
    #include"a.h"
    void fun2()
    {}
    
    //test.cpp
    #include<iostream>
    #include"a.h"
    using namespace std;
    
    int main()  
    {  
    	fun1();
    
        system("pause");  
        return 0;  
    }
    

    更多内容可看:C语言中关于.h和.c的问题

    展开全文
  • 简单来说,.h文件是头文件,用于函数的声明与定义,目的是让人清楚这个函数的功能以及其他一些信息相当于书中的目录。....hpp文件的实质就是将cpp文件中的代码混入h文件中,将函数的定义与实现写在一个文件中。 ...

    简单来说,.h文件是头文件,用于函数的声明与定义,目的是让人清楚这个函数的功能以及其他一些信息相当于书中的目录。.cpp文件是用于实现这个函数而编写的程序,相当于书中的章节。.hpp文件的实质就是将cpp文件中的代码混入h文件中,将函数的定义与实现写在一个文件中。

    展开全文
  • VS2019切换.h文件和.cpp文件快捷方式 1.按下 Ctrl + K Ctrl + O

    VS2019切换.h文件和.cpp文件快捷方式

    1.按下 Ctrl + K 和Ctrl + O

     

    展开全文
  • .h文件是声明类,变量函数,.cpp文件是.h文件中声明的对象的具体实现初始化,记得在.cpp文件开头加上#include "名字.h" 把 .h.cpp文件关联起来; 最简单的例子: test.h: class test { public: int a; ...
    .h文件是声明类,变量和函数,.cpp文件是.h文件中声明的对象的具体实现和初始化,记得在.cpp文件开头加上#include "名字.h" 把 .h和.cpp文件关联起来;
    
    最简单的例子:
    test.h:
        class test
        {
          public:
            int a;
            test();
            ~test();
            void function();
        };
    test.cpp
        #include "test.h"
        test::test()
        {
           a = 0; //a 的初始化
        }
        test::~test()
        {
        }
        void test::function()
        {
        }
    展开全文
  • C++——如何理解.h文件和.cpp文件

    千次阅读 2019-01-15 10:49:11
    建立一个以类为名字的XX.h文件,声明类,再建立一个相同名字的XX.cpp文件(要#include “XX.h”),实现类中的函数, 在有main 函数的.cpp里声明函数,建一个与函数名一样的.cpp文件,实现该函数;并且要 #include ...
  • C++ .h和.cpp文件总结

    2013-05-03 10:30:57
    总结了.h文件能做什么,.cpp文件能做什么,总结了.h文件的本质,方便新手在遇到文件包含、类型声明、变量定义时能理清.h与.cpp关系,纯属个人总结文档。
  • 理论上来说cpp文件与头文件里的内容,只要是C语言所支持的,无论写什么都可以的,比如你在头文件中写函数体实现,任何一个cpp文件包含此头文件就可以将这个函数编译成目标文件的一部分(编译是以cpp文件为单位的,...
  • C++中为什么要有.h文件和.cpp文件

    千次阅读 2016-02-14 11:34:03
    1,.h文件是不会被编译器编译的,而每个.cpp文件都会被编译,生成一个.obj文件。 2,这两个文件的名称不一定非要一样,只是为了方便阅读而已。在编译时,会根据#include去查找对应的.h文件 继续整理中.......
  • c++的.h和.cpp文件

    千次阅读 2019-05-15 19:54:35
    .h文件是不对外隐藏的, .cpp文件在编译后对外隐藏---这是最本质的特点和区别 .h.cpp文件本质上是没有什么区别的,.h文件实现的功能是声明本文件或.cpp文件中需要被别人使用或知道的变量、类型、函数及宏定义等。....
  • 解决方法一:同时存在.h.cpp,cpp中函数已经定义,依旧提示无法解释的...这次出现的原因应该是本人一开始在.h文件中定义函数,而没有创建一个cpp文件,VS把它当成cpp来用吧 后来本人又创建了一个cpp文件,C/C++编...
  • 主要介绍了Python实现计算文件夹下.h和.cpp文件的总行数,本文直接给出实现代码,需要的朋友可以参考下
  • 1.进入存放所有.cpp和.h文件的文件夹路径 2.输入 g++ -c alien.cpp events.cpp gas_stations.cpp main.cpp officer.cpp planets.cpp spaceship.cpp spaceships.cpp trading_stations.cpp -std=c++11 3.输入 g++ ...
  • ado2.h和ado2.cpp文件

    2011-04-06 11:52:36
    VC++封转的ado文件,帮助实现ado数据库连接等等功能
  • 在阅读一个较大的解决方案中,对于其他文件夹下的.h和.cpp文件,有时候#include“XXX.h”文件,有时候是#include“XXX.cpp”文件,而且二者还不能更换。下面就好好分析一下他们二者的区别。 ...
  • .cpp文件、.rc文件、.h文件区别

    万次阅读 2018-05-14 09:32:38
    .h类的头文件里面只放入函数声明,宏定义,函数原型,而具体的实现在.cpp文件里面;.rc文件是资源文件,包括比如对话框、菜单、图标、字符串等资源信息。使用.rc资源文件的目的是为了对程序中用到的大量的资源进行...
  • VS:导入.h和.cpp文件的办法

    千次阅读 2019-12-31 14:14:14
    VS:导入.h.cpp文件的办法1. 背景2. 只需导入.h文件2.1 复制粘贴2.2 绝对地址2.3 配置环境3. 导入.h.cpp文件3.1 复制粘贴3.2 绝对路径3.3 链接库4. 总结 1. 背景   当使用VS进行C/C++编程,偶尔需要导入外部...
  • 自动从.h文件中提取类中的成员函数信息,在.cpp文件中生成代码框架。用python写的,在python 3.1下测试的,如果是2.x,里面有一行异常处理的地方不太一样,参见代码中的说明。 直接运行脚本不带参数,会有一个简短的...
  • SerialPort.h和SerialPort.cpp文件

    热门讨论 2011-08-17 19:46:00
    SerialPort.h和SerialPort.cpp文件,WinSocket编程中用于操作串口的的类
  • QT 从COM组件里导出.h和.cpp文件
  • VS Code:导入.h和.cpp文件运行程序

    千次阅读 多人点赞 2019-12-30 17:02:10
    VS Code:导入.h和.cpp文件的方法1. 背景2 测试文件3. 方法4. 总结 1. 背景   在进行C/C++总会需要导入一些文件,如.h和.cpp文件。现总结使用VS Code编译运行C/C++程序时,导入.h和.cpp文件的解决方法。 2 测试...
  • Qt由ui文件生成.h和.cpp文件的方法

    千次阅读 2013-09-04 12:04:19
    由ui文件生成.h.cpp文件 生成.cpp文件 $uic myform.ui -i myform.h -o myform.cpp 生成.h文件 $uic myform.ui -o myform.h
  • C++之*.h和*.cpp文件详解

    千次阅读 2017-02-09 19:25:53
    *.h文件做的是类的声明,包括类成员的定义函数的声明,而*.cpp文件做的类成员函数的具体实现(定义)。一个*.h文件和*.cpp文件一般是配对的。在*.cpp文件的第一行一般也是#include"*.h"文件,其实也相当于把*.h...
  • .h和.cpp文件区别

    千次阅读 2019-06-22 03:35:50
    首先,我们可以将所有东西都放在一个.cpp文件内. 然后编译器就将这个.cpp编译成.obj,obj是什么东西? 就是编译单元了.一个程序,可以由一个编译单元组成, 也可以有多个编译单元组成. 如果你不想让你的源代码变得很难...
  • C语言后缀.h文件和.c文件作用和区别

    万次阅读 多人点赞 2019-05-31 09:01:30
    简述C语言中.h文件和.c文件作用和区别 在c语言学习过程中,对.h文件和.c文件不甚了解,参考其他资料后对它进行简要分析: .h文件和.c文件作用 使用.h文件和.c文件的原因 .h文件和.c文件作用 xx.h文件.h中一般放...
  • 对于很多工程来说,我们不用每一个类都需要自己来写,如果有别人已经编写好的类,我们可以拿过来直接...首先你得把自定义的.h和.cpp文件右键添加到你的MFC工程中,然后再#include引用之。 头文件---->添加---->现有项
  • cpp文件和.h文件

    2013-06-11 11:59:06
    .h文件需要时#include进来,不参与编译。 cpp文件参与编译。 如果变量的定义写在cpp文件里,无需include什么文件,就可以编译进来。如需在其它文件中使用,只要关键字extern即可。
  • 把private声明从.h文件移到.cpp文件

    千次阅读 2007-11-09 11:50:00
    把private声明从.h文件移到.cpp文件(转载请注明来源于金庆的专栏)在*.h文件中定义一个类时,理论上应该仅定义其公共接口,而不必声明其私有的成员,因为私有的成员属于实现部分,理应声明在.cpp文件中。...
  • vs中.h文件与.cpp文件之间的切换

    千次阅读 2015-04-20 14:25:41
    拒绝繁琐!快捷键实现vs中.h文件与.cpp文件之间的切换

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 306,487
精华内容 122,594
关键字:

.h文件和.cpp文件的区别