为什么使用模板:

  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. 注册鼠标右键CMD

    Windows Registry Editor Version 5.00 [-HKEY_CLASSES_ROOT\Directory\shell\runas] [HKEY_CLASSES_ROOT\D ...

  2. 自定义控件DataPager

    在最近的一个项目中,涉及到一个自定义翻页控制的控件,下面就这一个控件做详细的说明,这个自定义控件的主要作用是对数据源进行翻页控制,比如说:“上一页.下一页.首页.末页”等相关操作,由于在一个项目中有多 ...

  3. 如何禁止复制电脑文件到U盘、禁止U盘拷贝文件

    在公司局域网中,有时候我们处于保护电脑文件安全和商业机密的需要,会禁止局域网电脑使用U盘.禁用USB存储设备:或者禁止通过U盘复制电脑文件.禁止U盘拷贝公司电脑文件.那么,怎样实现呢?本文提供两种方法 ...

  4. /include/caffe/common.cuh(9): error: function "atomicAdd(double *, double)" has already been defined

    https://stackoverflow.com/questions/39274472/error-function-atomicadddouble-double-has-already-been- ...

  5. iTunes 12.7 没有应用程序选项了,重新安装iTunes 12.6.3

    iTunes 12.6.3 下载地址: Mac http://t.cn/RO5rIfE Win 32 http://t.cn/ROtta1T Win64 http://t.cn/ROtta1n 安装好 ...

  6. spring cloud 入门系列一:初识spring cloud

    最近看到微服务很火,也是未来的趋势, 所以就去学习下,在dubbo和spring cloud之间我选择了从spring cloud,主要有如下几种原因: dubbo主要专注于微服务中的一个环节--服务 ...

  7. 【AtCoder010】A - Addition(奇偶)

    AtCoder Grand Contest 010 A题 题目链接 题意 n个数,每次取两个奇偶性相同的数用他们的和代替他们,问最后能否只剩下一个数. 题解 因为奇偶相同的两个数之和一定是偶数,所以Y ...

  8. 自学Linux Shell11.5-执行数字运算

    点击返回 自学Linux命令行与Shell脚本之路 11.5-执行数字运算 1. Shell基本运算符 Shell 和其他编程语言一样,支持多种运算符,包括: 算数运算符 关系运算符 布尔运算符 字符 ...

  9. GNOME Shell Extension常用扩展

    这篇博文的,主要目的是为了方便我和大家安装GNOME扩展.我将我安装过的所有扩展列在此处. 常用扩展 Clipboard Indicator https://extensions.gnome.org/ ...

  10. plink, vcftool计算等位基因频率(allele frequency,vcf)

    计算等位基因频率有两种方式,第一种用vcftool计算: /path/to/vcftools --vcf file.vcf --freq --chr 1 --out filefreq 很简单的一个命令 ...