你的头
文件中如果没有相关
函数的实现方法,即使你包含这个
头文件也是没有用的。其实头文件就是一个函数的集合体,你先把所需要的函数全部定义好,然后放在某个你自己命名的头文件中。以后只要你需要某个函数的时候你就可以直接包含这个头文件。然后直接调用你定义过的函数就行了。c++会自动在包含的头文件中寻找函数的定义(不是在你的cpp文件中寻找定义),然后执行相关的函数。如果不是放在系统目录下面你可以包含全部的路径 例如 #include"D:\\MyHead.h" 如果是在cpp文件中寻找你定义的函数,那么如果你把那个cpp文件删除了,那岂不是会有编译错误。源文件不是必须的。比方说 我在aaa.h里定义了一个函数的声明,然后我在aaa.h的同一个目录下建立aaa.c , aaa.c里定义了这个函数的实现,然后是在main函数所在.c文件里#include这个aaa.h 然后我就可以使用这个函数了。 main在运行时就会找到这个定义了这个函数的aaa.c文件。这是因为:main函数为标准C/C++的程序入口,编译器会先找到该函数所在的文件。假定编译程序编译myproj.c(其中含main())时,发现它include了mylib.h(其中声明了函数void test()),那么此时编译器将按照事先设定的路径(Include路径列表及代码文件所在的路径)查找与之同名的实现文件(扩展名为.cpp或.c,此例中为mylib.c),如果找到该文件,并在其中找到该函数(此例中为void test())的实现代码,则继续编译;如果在指定目录找不到实现文件,或者在该文件及后续的各include文件中未找到实现代码,则返回一个编译错误.其实include的过程完全可以“看成”是一个文件拼接的过程,将声明和实现分别写在头文件及C文件中,或者将二者同时写在头文件中,理论上没有本质的区别。以上是所谓动态方式。对于静态方式,基本所有的C/C++编译器都支持一种链接方式被称为Static Link,即所谓静态链接。在这种方式下,我们所要做的,就是写出包含函数,类等等声明的头文件(a.h,b.h,...),以及他们对应的实现文件(a.cpp,b.cpp,...),编译程序会将其编译为静态的库文件(a.lib,b.lib,...)。在随后的代码重用过程中,我们只需要提供相应的头文件(.h)和相应的库文件(.lib),就可以使用过去的代码了。相对动态方式而言,静态方式的好处是实现代码的隐蔽性,即C++中提倡的“接口对外,实现代码不可见”。有利于库文件的转发.c文件和.h文件的概念与联系
引用自:http://blog.csdn.net/shi_869160/article/details/5714851
望采纳
模板的实现要放在头文件里就是你定义的地方。。不然编译的时候找不到。。
定义一个类一般都是在头文件中进行类声明,在cpp文件中实现,但使用模板时应将实现代码和声明代码均放在头文件中。如:
test.h
template<class T>
class CTest
{
public:
T&GetValue()
void SetValue(const T&_Value)
protected:
T m_Value
}
test.cpp
template<class T>
T&CTest<T>::GetValue()
{
return m_Value
}
template<class T>
void CTest<T>::SetValue(const T&_Value)
{
m_Value = _Value
}
在这儿test.cpp中的内容应放在test.h中,否则在生成最终可执行程序时就会出现错误(在链接时会出错)。因为在编译时模板并不能生成真正的二进制代码,而是在编译调用模板类或函数的CPP文件时才会去找对应的模板声明和实现,在这种情况下编译器是不知道实现模板类或函数的CPP文件的存在,所以它只能找到模板类或函数的声明而找不到实现,而只好创建一个符号寄希望于链接程序找地址。但模板类或函数的实现并不能被编译成二进制代码,结果链接程序找不到地址只好报错了。
《C++编程思想》第15章(第300页)说明了原因:模板定义很特殊。由t e m p l a t e <…>处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。
评论列表(0条)