c++类模版
2014-02-19 21:25
453 查看
上一篇讲了c++的函数模板,类模板是在比类更高级层次上的抽象,可以用类模板来创建类。简单的说,类模板就是一个抽象的类。
类模板、类及对象的关系
1、类模板定义的语法格式如下:
template <class T1, class T2, …>
class 类名
{
类成员声明
}
类模板定义中各部分的意义和函数模板定义中各部分的意义几乎相同。
2、代码实例
以下是一个类模板的实例,CStore为类模板,在主函数main()中调用。
Store.h中写入:
Store.cpp中写入:
Test.cpp中写入:
注:C++中,我们习惯将类的定义放在.h文件,而将类的实现放在.cpp文件中。而在使用这个类的时候包含它的头文件即可。但是这样使用会产生这样一种错误:
1>test.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall CStore<int>::~CStore<int>(void)" (??1?$CStore@H@@QAE@XZ),该符号在函数 "void __cdecl test(void)" (?test@@YAXXZ) 中被引用
在网上查了一些大虾写的博客,终于找到原因了:
在类模板的声明和定义中把.h与.cpp分离
现总结一条:在使用类模板技术时,可在.h中实现,也可在.h和.cpp中分开实现,若用.h实现,不要在文件中加入非类模板代码,可避免重写定义错误.
这组错误信息和project中不加入Store.cpp的错误信息一样,即没有CTpl<char>的实现代码
我们把Store.cpp包涵到main.cpp中,问题解决。
3、几点说明
1)类模板中,表示一个类是模板名加<模板参数>,如在一个类模板定义中用到另一个类模板时,采用以下方式定义。:
Template <class T>
Class TRect{
public:
TRect();
Get();
……
Private:
Tcoord<T> p1; // TCoord <T>表示一个类。
……
};
2)如果构造函数声明和实现分开时,构造函数实现的函数名应该是如下形式:
模板名称<模板参数>::模板名称() //注意域前和域后不一致
对应,成员函数实现时格式如下:
模板名称<模板参数>::函数名()
3)类模板的实现和声明分开时,每个带模板参数的成员函数实现时,必须定义模板参数,参数名可以和申明不同。如:
template <class TT> //必须定义参数名,但是模板参
//数名可以不同,这里T变为了TT
TT TCoord <TT>::getx()
{
return x;
}
类模板、类及对象的关系
1、类模板定义的语法格式如下:
template <class T1, class T2, …>
class 类名
{
类成员声明
}
类模板定义中各部分的意义和函数模板定义中各部分的意义几乎相同。
2、代码实例
以下是一个类模板的实例,CStore为类模板,在主函数main()中调用。
Store.h中写入:
#pragma once #include <iostream> using namespace std; template <class T> //仓库类 class CStore { public: CStore(void);//默认形式(无形参)的构造函数 ~CStore(void); T GetElem(void);//提取数据函数 void PutElem(T x);//存入数据函数 private: T item;//item 用于存放任意类型的数据 int haveValue;//haveValue标记item是否已被存入内容 };
Store.cpp中写入:
#include "StdAfx.h" #include "Store.h" //以下实现各成员函数 //注意:模板类的成员函数,若在类外实现,则必须是模板函数,即所有函数 // 均以CStore <T>修饰! template <class T> CStore<T>::CStore(void):haveValue(0) //参数初始化表初始化haveValue元素为0 { } template <class T> CStore <T>::~CStore(void) { } template <class T> T CStore<T>::GetElem(void) { if(haveValue==0) { cout<<"No item present!"<<endl; //exit(1); } return item; } template <class T> void CStore<T>::PutElem(T x) { haveValue++; item=x; }
Test.cpp中写入:
// test.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <Windows.h> #include <iostream> using namespace std; #include "Store.h" #include "Store.cpp" struct Student//结构体Student { int id;//学号 float gpa;//平均分 }; void test() { Student g={1000,23}; CStore<int> S1,S2; CStore<Student> S3; CStore<double> D; S1.PutElem(3); S2.PutElem(-7); cout<<S1.GetElem()<<" "<<S2.GetElem()<<endl; Sleep(1000); S3.PutElem(g); cout<<"The studnet id is "<<S3.GetElem().id<<endl; cout<<"The studnet gpa is "<<S3.GetElem().gpa<<endl; Sleep(1000); D.PutElem(3.1415); cout<<"Retrieving object D "; cout<<D.GetElem()<<endl; Sleep(1000); } int _tmain(int argc, _TCHAR* argv[]) { test(); cout<<"测试完毕!"<<endl; Sleep(10000); system("pasue"); return 0; }
注:C++中,我们习惯将类的定义放在.h文件,而将类的实现放在.cpp文件中。而在使用这个类的时候包含它的头文件即可。但是这样使用会产生这样一种错误:
1>test.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall CStore<int>::~CStore<int>(void)" (??1?$CStore@H@@QAE@XZ),该符号在函数 "void __cdecl test(void)" (?test@@YAXXZ) 中被引用
在网上查了一些大虾写的博客,终于找到原因了:
在类模板的声明和定义中把.h与.cpp分离
现总结一条:在使用类模板技术时,可在.h中实现,也可在.h和.cpp中分开实现,若用.h实现,不要在文件中加入非类模板代码,可避免重写定义错误.
这组错误信息和project中不加入Store.cpp的错误信息一样,即没有CTpl<char>的实现代码
我们把Store.cpp包涵到main.cpp中,问题解决。
3、几点说明
1)类模板中,表示一个类是模板名加<模板参数>,如在一个类模板定义中用到另一个类模板时,采用以下方式定义。:
Template <class T>
Class TRect{
public:
TRect();
Get();
……
Private:
Tcoord<T> p1; // TCoord <T>表示一个类。
……
};
2)如果构造函数声明和实现分开时,构造函数实现的函数名应该是如下形式:
模板名称<模板参数>::模板名称() //注意域前和域后不一致
对应,成员函数实现时格式如下:
模板名称<模板参数>::函数名()
3)类模板的实现和声明分开时,每个带模板参数的成员函数实现时,必须定义模板参数,参数名可以和申明不同。如:
template <class TT> //必须定义参数名,但是模板参
//数名可以不同,这里T变为了TT
TT TCoord <TT>::getx()
{
return x;
}
相关文章推荐
- 关于指针的一些事情
- 设计模式之行为型模式 - 调用行为的传递问题
- [div+css]晒晒最新制作专题推广页模板
- 2008大学生入党申请书 模板
- IMAIL多语言模板两套Outlook&Gmail模板下载
- C/C++数据对齐详细解析
- C++中引用的使用总结
- C与C++之间相互调用实例方法讲解
- C++中引用(&)的用法与应用实例分析
- 解析C++ 浮点数的格式化输出
- 深入分析C++中几个最不常用的关键字
- c++中inline的用法分析
- 深入解析C++ Data Member内存布局
- 从汇编看c++中默认构造函数的使用分析
- 关于C++中的友元函数的一些总结
- C++的sstream标准库详细介绍
- 基于C++自动化编译工具的使用详解
- 浅谈C++中的string 类型占几个字节
- C/C++ 宏详细解析
- 深入分析C++中两个大数相乘结果不正确的问题