c++类模板是怎么理解

2024-11-16 15:32:44
推荐回答(5个)
回答(1):

模板类英文为class template,template的中文翻译为模板,所以模板类的意思其实是:类的模板。
顾名思义,模板类是相当于一个模具,当参数给定时,生成具体的类,也叫实例化。它的提出主要是为了减少代码重复。
例如,我们可以用下面的代码交换两个数b和c
a = b;
b = c;
c = a;
这个交换过程与a,b,c的具体类型没有关系,因此我们可以用它来交换两个整数,或者两个浮点数。更一般的,我们可以用来交换两个具有赋值运算符的类型。因此,可以用模板进行一般化:
template
void swap(T &b, T &c){
a = b;
b = c;
c = a;

}
当然,上面介绍的这个不是模板类,而是模板函数。不过他们的概念是类似的。其中一开始的template代表后面尖括号中的是模板参数(类似于函数的参数),class代表参数是类(相应的,可以用template来声明整型参数)。后面的代码和的函数基本没有区别,只是用T来代替了具体的类型,例如int,double等。根据需要我们可以用swap(b,c)来交换两个整数,swap(b,c)交换两个浮点数。由于编译器可以根据b,c的具体类型推导T的具体含义,因此可以简写为swap(b,c)。
回到模板类,假设我们需要一个类型来代表动态数组,且该类型支持size成员函数。如果是整型的类,我们可能会写
class vector_int{
size_t size() const;

};
如果某一天,我们又需要浮点类型的动态数组,可能又会写
class vector_double{
size_t size() const;

};
于是就会发现它们的代码是如此的类似,因此我们希望将它一般化。如同swap函数的做法,我们将它定义为模板类:
template
class vector{
size_t size() const;
};
因此,vec_int等同于vector,而vector_double等同于vector。因为运用模板类的语法类似于
vector a;
因此,编译器没办法为我们推导T的具体含义,所以不能像模板函数一样进行简写。
当然,上面是比较简单的情况,有时候我们需要的类在大多数情况下是一样的,但是对于某几个特殊情形可能不太一样,例如我们可能希望对于bool类型的数组能尽量减少内存的使用,用一个比特位代表一个bool值。从而,我们的数组不是通过bool a[10]的形式来定义。在这种情况下,c++提供了模板特化,也就是说当模板的参数取某个具体的值时,我们使用不同的模板,定义方式如下:
template<>
class vector{
size_t size() const;
};

回答(2):

你不要跟着他绕,越绕越头晕,你只要记住这里的T代表一种类型就行了。模版实例化时只是把T用相应的类型替换。
如简单的min模版:
template
T min(T a, T b){return a
实例化:
int x = 100;
int y = 200;
int z = min(x,y); //这里的x、y都为int型,就相当于实例化了一个int型的min模版,你把int代上面T就清楚了

类模版也是一样的
template//也可用template,并且这是最新的C++标准
class C2DPoint //2D点坐标模版
{
public:
C2DPoint(T x=0, T y=0):m_x(x), m_y(y){}

void X(T x){m_x = x;}
void Y(T y){m_y = y;}

T X(void)const{return m_x;}
T Y(void)const{return m_y;}

void Print()const;
private:
T m_x, m_y;
};

template
void C2DPoint::Print()const
{
std::cout<<"x:"<}
int main()
{
C2DPoint p0; //这里相当于把int代回模版中T的位置
p0.X(10);
p0.Y(20);
p0.Print();
C2DPoint p1(100, 200.5);//这里相当于把float代回模版中T的位置
p1.Print();
return 0;
}

回答(3):

template 算不上参数。这句主要是说类Smemory使用了带参数 T 的类模板,是模板声明。
就是说Smemory类里使用了 T 类型的数据或对象。在具体使用时,要进行初始化。例如:要建立类 Smemory的对象。可以如下:
Smemory obj;
Smemory obj1;
还可以进行其他类型的初始化。
自己写的一个简单的图形类,可以参考一下:
#include
using namespace std;
const double PI=3.1415926;
template
class Shape
{
protected:
T x,y;
public:
Shape(T tx,T ty){x=tx;y=ty;}
virtual T area()=0;
virtual T length()=0;
virtual void show()=0;
};

template
class Circle:public Shape
{
protected:
T radius;
public:
Circle(T x,T y,T r):Shape(x,y){radius=r;}
T area(){return PI*radius*radius;}
T length(){return 2*PI*radius;}
void show(){cout<<"Area="<};

template
class Rectangle:public Shape
{
protected:
T h,w;
public:
Rectangle(T x,T y,T th,T tw):Shape(x,y){h=th;w=tw;}
T area(){return h*w;}
T length(){return 2*(h+w);}
void show(){cout<<"Area="<};

void main()
{
Circle Cobj(2,3,1);
Rectangle Robj(2,3,3,4);
Cobj.show();
Robj.show();

void (Shape::*pf)();
pf=Shape::show;
(Cobj.*pf)();
(Robj.*pf)();

Shape *p;
p=&Cobj;
p->show();
p=&Robj;
p->show();

system("pause");
}

回答(4):

T 就是定义了一种类型 在后面使用的时候 会给他一个初始化的值
#include
using namespace std;
const int StackSize=100;
template
class SeqStack
{
public:
SeqStack(){top=-1;}
~SeqStack(){}
void Push(T x);
T Pop();
T GetTop(){if(top!=-1)return data[top];}
bool Empty();
void Print();
private:
T data[StackSize];
int top;
};
template
bool SeqStack::Empty()
{
if (top==-1)
return true;
else return false;
}

template
void SeqStack::Push(T x)
{
if(top == StackSize-1)throw"上溢";
top++;
data[top]=x;
}
template
T SeqStack::Pop()
{
if (top==-1)throw"下溢";
T x=data[top];
top--;
return x;
}
template
void SeqStack::Print()
{
int i;
cout<<"the stack is:"< cout<<"-------------"< for(i=top;i>=0;i--)
{
cout<<" "< cout<<"-------------"< }
}
int main()
{
SeqStackStack;
int a,b,tab,f;
int flag=1;
f=0;
while(f==0)
{
cout<<"***************************"< cout<<"*1.push *"< cout<<"*2.pop *"< cout<<"*3.if empty *"< cout<<"*4.get top data *"< cout<<"*5.exit *"< cout<<"***************************"< cin>>tab;
switch (tab)
{
case 1:
{
cout<<"please input a number:"< cin>>a;
Stack.Push(a);
Stack.Print();
break;
}
case 2:
{
b=Stack.Pop();
cout<<"the number is:"< Stack.Print();
break;
}
case 3:
{
if(Stack.Empty())cout<<"true"< else cout<<"flase"< break;
}
case 4:
{
a=Stack.GetTop();
cout< break;
}
default:
{
f=1;
}
}
}
Stack.~SeqStack();
return 0;
}

回答(5):

里面放一个类型,这个类里的所有T都成这个类型