你所不知道的事儿--C++类模板的声明和实现不能分离
2015-09-06 15:05
351 查看
也许你具有良好的编程习惯,在定义一个类的时候总会把声明和实现分离开,位于不同的文件中。比如你定义一个类A,首先创建一个.h文件,代码如下:
接下来你创建一个.cpp文件实现类的声明,代码如下:
接下来就要使用这个类了,新建一个cpp文件,代码如下:
可能你和我一样,按照上诉编程习惯来写类模板,这简直就是个遭遇!
将上面的类A改为类模板,.h文件如下:
把.cpp文件改为如下:
main函数的.cpp文件代码改为:
此时运行,错误发生。如果我们将类模板的声明和定义写在一个文件中呢,即把.h和.cpp文件合并,得到如下代码:
这样在进行调试,则没有错误。
所以,我们得到:
类模板不能将声明和实现分离在两个文件中!!
但是究其原因:
《C++编程思想》中这么说:模板定义很特殊。由template<…>处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。
class A { public: A(int b); void show(); ~A(); private: int a; }
接下来你创建一个.cpp文件实现类的声明,代码如下:
#include"classA.h" #include<iostream> A::A(int b) { a = b; } void A::show() { std::cout << a << std::endl; } A::~A() { }
接下来就要使用这个类了,新建一个cpp文件,代码如下:
#inlucde"classA.h" #include<iostream> int main() { A a(10); a.show(); return 0; }
可能你和我一样,按照上诉编程习惯来写类模板,这简直就是个遭遇!
将上面的类A改为类模板,.h文件如下:
template<class T> class A { public: A(T b); void show(); ~A(); private: T a; }
把.cpp文件改为如下:
#include"classA.h" #include<iostream> template<class T> A<T>::A<T>(T b) { a = b; } template<class T> void A<T>::show() { std::cout << a << std::endl; } template<class T> A<T>::~A<T>() { }
main函数的.cpp文件代码改为:
#inlucde"classA.h" #include<iostream> int main() { A<int> a(10); a.show(); return 0; }
此时运行,错误发生。如果我们将类模板的声明和定义写在一个文件中呢,即把.h和.cpp文件合并,得到如下代码:
template<class T> class A { public: A(T b); void show(); ~A(); private: T a; }
template<class T>
A<T>::A<T>(T b)
{
a = b;
}
template<class T>
void A<T>::show()
{
std::cout << a << std::endl;
}
template<class T>
A<T>::~A<T>()
{
}
这样在进行调试,则没有错误。
所以,我们得到:
类模板不能将声明和实现分离在两个文件中!!
但是究其原因:
《C++编程思想》中这么说:模板定义很特殊。由template<…>处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。
相关文章推荐
- c语言之enum
- 详解C语言中accept()函数和shutdown()函数的使用
- noip 2012 国王游戏
- c++语法小知识1
- C++11系列学习之三----array/valarray
- 【C++】多重继承
- C++中引用(&)的用法和应用实例
- Effective C++ Item3
- C++面试题
- C++中tuple类型
- 【C++】继承时构造函数和析构函数
- Effective C++——条款25(第4章)
- C语言--enum,typedef enum 枚举类型详解
- 漫谈C指针第八讲---参数传递的三道题目
- C++/C, Java学习资料
- C++函数声明和定义深度解析(转)
- C++ 11 学习2:空指针(nullptr) 和 基于范围的for循环(Range-based for loops)
- C++中引用(&)的用法和应用实例
- C++11系列学习之二-----lambda表达式
- C++的第一步:Visual Studio 6.0~2013 各版本编译器下载汇总