为什么使用模板:

  C++重载(overloading),重载函数一般含有不同的参数个数或不同的参数类型。如果使用MAX函数对不同类型的求最大值,就要定义不同的重载函数:

  

int max(int x,int y)
{
if(x>y)
return x;
else
return y;
} float max(float x,float y)
{
if(x>y)
return x;
else
return y;
}

但是如果要用double型,又需要重新定义。。。

模板就是为了解决重载函数定义不全的问题,它可以实现类型参数化,即把类型定义为参数,从而实现代码的可重用性。模板分为两类:函数模板和类模板

函数模板:

Template<class 或 typename T>

template是一个声明的模板的关键字,表示声明一个模板关键字class不能省。

template <class T>
T min(T x,T y) {
return(x<y)?x:y;
}

类模板定义:

template <class T>

class 类名{

};

template <class T1,class T2>
class student{
T1 a;
T2 b;
public:
student(T1 a,T2 b);//constructor
void show();
}; template<class T1, class T2>
student<T1,T2>::student(T1 a,T2 b):a(a),b(b){}
template<class T1,class T2>
void student<T1,T2>::show()
{
cout<<a<<b<<endl;
}
int main()
{
student<char ,char> s('a','b');
s.show();
return ;
}

把类的属性定义为private,保护数据,不能外部随意访问,但是可以定义一个访问内部数据的函数接口。也可以定义一个修改内部属性的函数(那这与外部访问数据和修改数据有什么区别,这样可以在修改函数里加各种限制。哈哈)

array < int > a();

array < int >表明用int类型来代替模板类中的类参数“T”,编译器会将模板类array中所有的类参数T都用int来代替。例如类中的私有成员变量“T * num;”会被替换为“int * num;”。对类中的成员函数也会进行相同的替换,如“T & operator[]( int );”将会被替换为“int & operator[]( int );”。

using namespace std;
template< class T >
class array
{
public:
array( int );
T & operator[]( int );//操作符[]取第int个数,返回类型为T。。
const T & operator[] ( int )const;
int getlen() const { return length; }
~array();
private:
array(){};
int length;
T * num;
};
template < class T >
array< T >::array( int n )
{
num = new T[n];
length = n;
}
template < class T >
array< T >::~array()
{
delete[] num;
}
template< class T >
T & array< T > ::operator[] ( int i )
{
if( i < || i >= length )
throw string( "out of bounds" );
return num[i];
}
template< class T >
const T & array< T > ::operator[] (int i) const
{
if( i < || i >= length)
throw string( "out of bounds" );
return num[i];
}
template< class T >
ostream & operator<<( ostream & out, const array <T> & A )
{
for(int i=; i < A.getlen(); i++)
out<< A[i] << " ";
return out;
}
int main()
{
array< int > A();
for(int i = ; i < ; i++)
{
A[i] = *i;
}
cout<<A<<endl;
return ;
}

C++编程技巧:对象与实例的区别,new与不用new的区别:

  class A a; a 在栈里;

  class A a=new A; A 在堆里;

  new创建类对象需要指针接收,一处初始化,多处使用;     CTest* p= new CTest();//new申请的对象,则只有调用到delete时再会执行析构函数 ; 不用new   CTest mTest;//不需要手动释放,该类析构函数会自动执行

  new需要delete销毁

  new创建对象在堆空间

  频繁调用不适合用new,要申请和释放内存

用new 生成对象,上面的例子写为:

int main()
{
student<char ,char>* s=new student<char ,char >('a','b');
s->show();
delete(s);
return ;
}

(java中不同:JAVA:

  A a = new A();

  为A对象创建了一个实例,但在内存中开辟了两块空间:一块空间在堆区,存放new A()这个对象;

  另一块空间在堆栈,也就是栈,存放a,a的值为new A()这个对象的内存地址。因为java在JVM中运行,

  所以a 描述的内存地址不一定是这个对象真实内存的地址。

  Object o; // 这是声明一个引用,它的类型是Object,他的值为null,还没有指向任何对象,该引用放在内存的栈区域

  o = new Object(); // new Object()句,实例化了一个对象,就是在堆中申请了一块连续空间用来存放该对象。

  = // 运算符,将引向o指向了对象。也就是说将栈中表示引用o的内存地址的内容改写成了Object对象在堆中的地址。

  

  创建对象:student stu1 = new  student();

  通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。

  1)右边的"new  student",是以student类为模板,在堆空间里创建一个student类的对象(也简称为student对象)。

  2)末尾的()意味着,在对象创建后,立即调用student类的构造函数,对刚生成的对象进行初始化。

   构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。

  3)左边的"student stu1"创建了一个student类引用变量。所谓student类引用,就是以后可以用来指向某个

  student对象的对象引用,它指向的是某个student对象的内存地址(有点C语言中指针的味道)。

  4)"="操作符使对象引用指向刚创建的那个student对象。

    我们可以把这条语句拆成两部分:student  stu1;                 (1)

stu1 = new student();     (2)

    效果是一样的。

  C++ 如果直接定义类,如classA a; a 存在栈上(也意味着复制了对象a在栈中),如果classA  a = new classA就存在堆

非类型模板参数:

C++中:

Student  student(20) ;  //这里student是引用 对象分配在 栈空间中,这里只是我的理解

Student *student = new  Student(20);  //这里student是指针,new Student(20)是分配在堆内存空间的

  1. Student stu;//对象 stu 在栈上分配内存,需要使用&获取它的地址
  2. Student *pStu = &stu;//创建对象指针

在堆上创建对象,这个时候就需要使用前面讲到的new关键字

  1. Student *pStu = new Student;

在栈上创建出来的对象都有一个名字,比如 stu,使用指针指向它不是必须的。但是通过 new 创建出来的对象就不一样了,它在堆上分配内存,没有名字,只能得到一个指向它的指针,所以必须使用一个指针变量来接收这个指针,否则以后再也无法找到这个对象了,更没有办法使用它。也就是说,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数。栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积。

new A以及new A()的区别:

调用new分配的内存有时候会被初始化,而有时候不会,这依赖于A的类型是否是POD(Plain old data)类型,或者它是否是包含POD成员、使用编译器生成默认构造函数的类。POD class没有用户定义的析构函数、拷贝构造函数和非静态的非POD类型的数据成员。没有用户定义的构造函数,没有私有的或者保护的非静态数据,没有基类或虚函数。它只是一些字段值的集合,没有使用任何封装以及多态特性。

#include <iostream>  

using namespace std;  

struct A { int m; }; // POD
struct B { ~B(){}; int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(){}; int m; }; // non-POD, default-initialising m int main()
{
A *aObj1 = new A;
A *aObj2 = new A();
cout << aObj1->m << endl;
cout << aObj2->m << endl; B *bObj1 = new B;
B *bObj2 = new B();
cout << bObj1->m << endl;
cout << bObj2->m << endl; C *cObj1 = new C;
C *cObj2 = new C();
cout << cObj1->m << endl;
cout << cObj2->m << endl; delete aObj1;
delete aObj2;
delete bObj1;
delete bObj2;
delete cObj1;
delete cObj2; return ;
}

new A:不确定的值

new A():value-initialize A,由于是POD类型所以是zero initialization

new B:默认构造(B::m未被初始化)

new B():value-initialize B,zero-initialize所有字段,因为使用的默认构造函数

new C:default-initialize C,调用默认构造函数

new C():value-initialize C,调用默认构造函数

在所有C++版本中,只有当A是POD类型的时候,new A和new A()才会有区别。而且,C++98和C++03会有区别。

但是在Java中

Student  student(20) ;  //注意:java中没有这样实例化对象的, 要想得到一个对象 必须要new出来.

Student student ; //这个只是定义了一个引用 ,没有指向任何对象

Student student = new Student(20);   //定义了一个引用,指向堆内存中的student对象

常数,或指向外部链接对象的指针。

template <class T,MAXSIZE>
class Stack{
T elemsp[MAXSIZE];
};
Stack<int, > intStack;
Stack<int ,> intStack2;

C++中模板的使用的更多相关文章

  1. tornado学习笔记11 Web应用中模板(Template)使用应用实践

    上一篇中(Web应用中模板的工作流程分析),已经分析了模板的渲染流程,以及相关参数获取及设置原理.这篇主要讲述模板在实际应用案例. 11.1 需求 根据用户输入的两次密码,判断两次密码是否一致,并将判 ...

  2. wpf 获取datagrid中模板中控件

    //获取name为datagrid中第三列第一行模板的控件 FrameworkElement item = dataGrid.Columns[].GetCellContent(dataGrid.Ite ...

  3. c++中模板是什么?为什么要定义模板?

    一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...

  4. 多个so中模板单例的多次实例化

    在Android打包项目时,发现登录功能不能使用了,logcat中也没发现什么问题,最后一行一行log定位到了问题.原来是一个so文件中的构造函数被初始化二次!   这个单例是通过继承模板来实现的(暂 ...

  5. Django项目中模板标签及模板的继承与引用【网站中快速布置广告】

    Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...

  6. TP框架中模板赋值

    TP框架中模板赋值 $this->assign('name',$value); $this->name = $value; // 两种写法是等效的

  7. 关于 underscore 中模板引擎的应用演示样例

    //关于 underscore 中模板引擎的应用演示样例 <!doctype html> <html> <head> <meta charset=" ...

  8. 总结:WPF中模板需要绑定父级别的ViewModel该如何处理

    原文:总结:WPF中模板需要绑定父级别的ViewModel该如何处理 <ListBox ItemsSource="{Binding ClassCollection}"> ...

  9. tornado 学习笔记10 Web应用中模板(Template)的工作流程分析

             第8,9节中,我们分析Tornado模板系统的语法.使用以及源代码中涉及到的相关类,而且对相关的源代码进行了分析.那么,在一个真正的Web应用程序中,模板到底是怎样使用?怎样被渲染? ...

  10. AngularJS学习--- AngularJS中模板链接和图像 ng-src step6

    接上一篇文章,本文将主要介绍angularjs中的模板链接,和图像显示? 首先,切换分支,启动项目: git checkout step- npm start 1.效果 相较于前一篇文章,明显感觉多了 ...

随机推荐

  1. NodeJS中的require和import

    ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是CommonJS规范,使用require引入模块,使 ...

  2. KNN python实践

    本文实现了一个KNN算法,准备用作词频统计改进版本之中,这篇博文是从我另一个刚开的博客中copy过来的. KNN算法是一个简单的分类算法,它的动机特别简单:与一个样本点距离近的其他样本点绝大部分属于什 ...

  3. matplotlib绘图3

    #scatter fig=plt.figure() ax=fig.add_subplot(3,3,1)#3行3列 第一个图 n=128 X=np.random.normal(0,1,n) Y=np.r ...

  4. python常用命令和基础运算符

    基础运算符 http://www.cnblogs.com/alex3714/articles/5465198.html 身份运算符:is is not成员运算符:in not in ##in 判断元素 ...

  5. AWS、Azure和Google的云容器注册表有什么区别?

    亚马逊云计算服务(AWS).谷歌云服务和微软Azure,这三大公共云平台都提供Docker容器注册表.虽然他们的产品看起来很相似,但开发人员在做出选择之前,应该先了解价格和功能方面的差异. 公共云供应 ...

  6. BZOJ2843极地旅行社&BZOJ1180[CROATIAN2009]OTOCI——LCT

    题目描述 给出n个结点以及每个点初始时对应的权值wi.起始时点与点之间没有连边.有3类操作:  1.bridge A B:询问结点A与结点B是否连通. 如果是则输出“no”.否则输出“yes”,并且在 ...

  7. LOJ115 无源汇有上下界可行流(上下界网络流)

    假设初始流为每条边的下界.但这样可能流量会不守恒,我们需要在上面加上一个附加流使流量守恒.只要让每个点开始的出/入流量与原初始流相等就可以求出附加流了.那么新建超源S超汇T,令degree[i]表示流 ...

  8. MT【229】最小值函数

    已知定义域为$R$的函数,$f(x),g(x)$满足:$f(x)+g(x)=e^{-x^2+1}$,则$min\{f(x),g(x)\}$的最大值为______ 解答:$min\{f(x),g(x)\ ...

  9. [luogu4268][bzoj5195][USACO18FEB]Directory Traversal

    题目大意 给你\(n\)个文件的关系,求出某一个点,这个点到叶节点的长度的总距离最短.(相对长度的定义在题目上有说明) 感想 吐槽一下出题人,为什么出的题目怎么难看懂,我看了整整半个小时,才看懂. 题 ...

  10. 用DotNetOpenAuth实现基于OAuth 2.0的web api授权 (一)Getting Start

    1. 下载 源码下载 2. build solution,创建虚拟目录: 右健MyContatacts/MyPromo项目,选择Properties,点击左边的Web,点击 Create Virtua ...