曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3621|回复: 3
打印 上一主题 下一主题

通用类

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2011-11-18 20:34:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
除了 通用函数 外,还可以定义通用类。

通用类的定义形式如下:
[C++] 纯文本查看 复制代码
template <class Ttype> class class-name {
...
}

在上面定义中,Ttype 是类型名字占位符,在对类进行实例化时会用实际的数据类型替换它。如果需要多个通用数据类型,那么可以使用逗号分隔参数列。

在创建了通用类后,可以使用下面的通用形式来生成类的实例:
class-name<type> ob;
上面代码中,type 是对象需要使用的数据类型。通用类的成员函数也会自动成为通用函数,不需要显式的使用 template 来声明它们。

下面是一个简单的读写队列实例:
[C++] 纯文本查看 复制代码
using namespace std;

const int SIZE = 100;

//创建通用类
template <class QType> class queue {
        QType q[SIZE];
        int sloc, rloc;
public:
        queue() { sloc = rloc = 0; }
        void qput(QType i);
        QType qget();
};

//将一个对象放入queue中
template <class QType> void queue<QType>::qput(QType i)
{
        if (sloc == SIZE) {
                cout << "Queue is full.\n";
                return;
        }
        sloc++;
        q[sloc] = i;
}

//从queue中获得一个对象
template <class QType> QType queue<QType>::qget()
{
        if (rloc == sloc) {
                cout << "Queue Underflow.\n";
                return 0;
        }
        rloc++;
        return q[rloc];
}

int main()
{
        //创建两个整数类型数据的 queue 对象
        queue<int> a, b;
        a.qput(10);
        b.qput(19);
        a.qput(20);
        b.qput(1);

        cout << a.qget() << " ";
        cout << a.qget() << " ";
        cout << b.qget() << " ";
        cout << b.qget() << "\n";

        //创建两个双精度浮点型数据的 queue 对象
        queue<double> c, d;
        c.qput(10.12);
        d.qput(19.99);
        c.qput(-20.0);
        d.qput(0.986);

        cout << c.qget() << " ";
        cout << c.qget() << " ";
        cout << d.qget() << " ";
        cout << d.qget() << "\n";

        return 0;
}


运行输出:
10 20 19 1
10.12 -20 19.99 0.986
在上面程序中,声明了两种不同类型的队列对象,一种是 int 队列对象,另一种是 double 型队列对象:
[Plain Text] 纯文本查看 复制代码
queue<int> a, b;
queue<double> c, d;


注意,对象中的数据类型是放在尖括号中的。在创建对象时可以指定其数据类型,比如还可以指定:
[C++] 纯文本查看 复制代码
queue<char *> chptr;

尖括号中还可以是个结构体类型,比如:
[C++] 纯文本查看 复制代码
struct addr {
   char name[40];
   char city[30];
}


queue<addr> obj;

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2011-11-18 20:59:15 | 只看该作者

使用两个通用数据类型实例

如果在模板类的声明中需要使用多个通用数据类型,那么可以在 template 的定义中声明需要的全部数据类型,每个类型用逗号隔开。如下示例:
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;

template <class Type1, class Type2> class myclass
{
        Type1 i;
        Type2 j;
public:
        myclass(Type1 a, Type2 b)
        {
                i = a;
                j = b;
        }
        void show()
        {
                cout << i << ' ' << j << '\\n';
        }
};

int main()
{
        myclass<int, double> ob1(10, 0.23);

        myclass<char, const char *> ob2('X', "This is a test");

        ob1.show(); //输出整数和双精度浮点数
        ob2.show(); //输出字符和字符串

        return 0;
}

运行输出:
10 0.23
X This is a test
上面程序声明了两种类型的对象,对象 ob1 使用了 int 型和 double 型数据;而对象 ob2 则使用了字符和字符指针。在这两种情况中,编译器都会根据对象被创建时使用的数据类型而自动生成对应的成员变量和成员函数。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
板凳
 楼主| 发表于 2011-11-19 00:37:27 | 只看该作者

创建一个通用数组类

下面例子将通用类和重载运算符结合起来,创建一个通用的安全数组类 --- 只允许通过重载的运算符 [ ] 来访问数组,并且拦截越界的数组下标。这个类可以创建任意数据类型的数组对象。

测试代码
[C++] 纯文本查看 复制代码
#include <iostream>
#include <stdlib.h>

using namespace std;

const int SIZE = 10;

//通用类
template <class AType> class atype
{
        AType a[SIZE];  //通用数组
public:
        atype() {
                register int i;
                for (i = 0; i < SIZE; i++) a[i] = i;
        }
        AType &operator[] (int i);      //重载 [] 运算符,数组返回的是类型的引用
};

//为 atype 类型的数据提供边界检测
template <class AType> AType &atype<AType>::operator[](int i)
{
        if (i < 0 || i > SIZE-1) {
                cout << "\\nIndex value of ";
                cout << i << " is out-of-bounds.\\n";
                exit (1);
        }
        return a[i];
}

int main()
{
        atype<int> intob;       //整数数组对象

        atype<double> doubleob;         //双精度数组对象

        int i;

        cout << "Integer array: ";
        for (i = 0; i < SIZE; i++) 
                intob[i] = i;

        for (i = 0; i < SIZE; i++)
                cout << intob[i] << " ";
        cout << '\\n';

        cout << "Double array: ";
        for (i = 0; i < SIZE; i++)
                doubleob[i] = (double) i/3;

        for (i = 0; i < SIZE; i++)
                cout << doubleob[i] << " ";
        cout << '\\n';

        return 0;
}


运行输出:
Integer array: 0 1 2 3 4 5 6 7 8 9
Double array: 0 0.333333 0.666667 1 1.33333 1.66667 2 2.33333 2.66667 3

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
地板
 楼主| 发表于 2011-11-19 12:50:52 | 只看该作者

类的显示特例化

模板函数 一样,也可以对通用类进行显式特例化。与通用函数的显式特例化 一样,可以使用 template<> 进行类的显式特例化:
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;

template <class T> class myclass {
        T x;
public:
        myclass(T a) {
                cout << "Inside generic myclass.\\n";
                x = a;
        }
        T getx() { return x; }
};

//整数类型的显示特例化
template <> class myclass<int> {
        int x;
public:
        myclass(int a)
        {
                cout << "Inside myclass<int> specialization\\n";
                x = a * a;
        }
        int getx() { return x; }
};

int main()
{
        myclass<double> d(10.1);
        cout << "double: " << d.getx() << "\\n\\n";

        myclass<int> i(5);
        cout << "int: " << i.getx() << "\\n";

        return 0;
}

运行输出:
Inside generic myclass.
double: 10.1

Inside myclass<int> specialization
int: 25
上面程序中,注意显示特例化的语法格式:
template <> class myclass<int> {
它告诉编译器创建通用类 myclass 的整数类型特例,而在为其他类型创建类的特例化形式时则用同样的语法。

类的显式化特例扩展了通用类的使用范围,因为它允许你更容易处理一种或两种特殊的情况,而同时允许其他的类型则通过编译器自动处理。当然,如果你要创建很多的特例化,那么最好还是不要把模板类作为首要选择。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 10:49 , Processed in 0.067588 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表