`

模板和泛型编程???从P269继续

 
阅读更多

参考书 <C++ By Dissection>

 

In C++, there are 3 different ways to employ generic coding techniques:

         void* pointers,

         Templates,

         Inheritance.

 

一、为什么使用模板进行泛型编程更好

 

举例:通用数组拷贝

 

方法一、二:使用void* 和 template

可以用void*或template来实现“通用数组拷贝 ”,但是后者 有以下优势——

(1)按元素拷贝,不依赖平台,增强可移植性

        void*因为不知道每个元素的大小elementSize,只能将elementSize作为参数传入,但C++中类型的长度依赖平台,因此移植性不好。

(2)若源和目的数组类型不同,提供类型保护 (编译时报错unification error)。

        void*不能满足这个要求。

#include <iostream>
using namespace std;

//ordinary
int transfer1(int from[], int to[], int size){
    for(int i=0;i<size;i++){
            to[i]=from[i];
    }
    return size;
}

//void* generic assignment function
int transfer2(void* from, void* to, int elementSize, int size){
    int nBytes=elementSize*size;
    
    for(int i=0;i<nBytes;i++){
            static_cast<char*>(to)[i]=static_cast<char*>(from)[i];
    }
    return size;
}

//template generic assignment function
template<class T>
int transfer3(T* from, T* to, int size){
    for(int i=0;i<size;i++){
            to[i]=from[i];
    }
    return size;
}

template<class T>
void printArr(T from[], int size){
     for(int i=0;i<size;i++)
             cout<<from[i]<<"\t";
     cout<<endl;
}

int main(void){
    int a[10]={1,2,3,4,5,6,7,8,9,10},b[10];
    double c[20]={10,9,8,7,6,5,4,3,2,1},d[20];

    transfer1(a,b,10);
    printArr(b,10);
    
    //使用void* 只能逐字节拷贝
    transfer2(c,d,8,10);
    printArr(d,10);
    
    //使用模板,可以仍然逐元素拷贝 
    d[1]++;
    transfer3(d,c,10);
    printArr(c,10);
    
    //相比void*,template仍然提供类型保护(type-safety) 
    transfer3(a,c,10);  //报错
    transfer2(a,c,4,10); //不报错
    
    system("pause");
    return 0;
}

 

方法三:使用宏定义

我来评价一下宏定义实现泛型编程的优势和劣势——

 

(1)宏定义优势:

简单性(Simplicity)、习惯性(familiarity)、高效性(Efficiency)。

其中,习惯性是由于在C编程中使用宏(macros)的传统;高效性主要因为没有函数调用的开销。

 

(2)宏定义劣势:

没有类型保护(type-safety)、预期外的计算(unanticipated evaluations)、范围问题(Scoping problem)

其中,与使用模板对比,解释一下“预期外的计算”。例如,计算立方,

可以使用宏

#define CUBE(X)  ((X)*(X)*(X))

可以使用模板

template<class T> T cube(T x) {return x*x*x;}

现在需要计算(sqrt(7))³

如果使用宏,CUBE(sqrt(7)),因为是直接文本替换,计算了三次sqrt(7);

如果使用函数,cube(sqrt(7)),则只调用一次sqrt(7)。

这样一来,虽然宏没有函数调用的开销(使用对战的机制),但是重复的计算使得它的优势得不偿失:(

 

#include <iostream>
using namespace std;

#define COPY(A,B,N)\
        {int i; \
        for(i=0;i<(N);++i) (B)[i]=(A)[i];}

template<class T>
void printArr(T from[], int size){
     for(int i=0;i<size;i++)
             cout<<from[i]<<"\t";
     cout<<endl;
}

int main(void){
    int a[10]={1,2,3,4,5,6,7,8,9,10},b[10];
    double c[20]={10,9,8,7,6,5,4,3,2,1},d[20];
    
    COPY(a,b,10);
    printArr(b,10);
    
    system("pause");
    return 0;
}
 

二、使用模板

 

1. Template Class 模板类


2. Function Templates 函数模板
Many functions have the same code body, regardless of type(例如上面的例子)

 

 

 

 

 

分享到:
评论

相关推荐

    全国计算机二级C++等级考试真题及答案.pdf

    在C++语言中,模板是一种泛型编程机制,用于实现函数和类的泛型化。模板可以是函数模板,也可以是类模板。函数模板用于实现函数的泛型化,而类模板用于实现类的泛型化。 输入输出流 在C++语言中,输入输出流是用于...

    c++课件PPT教案.pptx

    首先,模板是C++中实现泛型编程的核心机制。它允许程序员编写能够处理不同类型数据的通用代码,无论是函数还是类。模板主要有两种形式:函数模板和类模板。 函数模板是一种通用函数,它不直接定义函数的行为,而是...

    Refcard大全.zip

    7. 函数模板和泛型编程。 8. C++11及更高版本的新特性,如lambda表达式,右值引用。 **gdb** gdb是GNU调试器,用于调试C和C++程序: 1. 启动gdb:运行已编译的程序,设置断点。 2. 控制执行:run(开始执行),...

    C++课本电子版

    C++是一种强大的、通用的编程语言,它在C语言的基础上扩展了面向对象和泛型编程的概念,使得程序设计更加灵活高效。C++的发展历程可以追溯到二十世纪七十年代,由Bjarne Stroustrup在C语言的基础上进行改进,旨在...

    -2014-1试卷B.doc

    C++模板是一种泛型编程工具,允许创建函数和类的通用版本,可以处理不同类型的数据。函数模板允许定义一个可以接受任意类型参数的函数,而类模板则可以生成通用的类。模板的目的是提高代码的复用性和灵活性,减少...

    华为C/C++类笔试/面试题

    - **解答:** 模板是C++中一种重要的泛型编程工具。它允许程序员编写通用的代码,可以在多种不同的数据类型上工作,而无需为每种类型显式地重写代码。模板的主要优势在于提高了代码的复用性和灵活性,减少了代码冗余,...

    C++期末复习--2.练习题_填空.docx

    13. 在函数模板的参数中,用`class`修饰的参数称为**类型**参数,用于泛型编程。 14. 假定类型参数用`T`表示,给定的两个函数`int cubin(int n)`和`double cubin(double n)`是函数模板的两个实例,那么该函数模板的...

    面向对象程序设计复习题.doc

    12. **模板**:模板是泛型编程的基础,可以用于类和函数。类模板实例化时,编译器会根据给定的模板参数生成一个类,选项B正确。 13. **标识符**:在C++中,标识符可以包含字母、数字和下划线,但不能以数字开头。...

    java2

    此外,C++还支持泛型编程,通过模板机制来实现。 - **C++的历史背景**:C++是由Bjarne Stroustrup在20世纪80年代初开发的。他最初将C++称为“C with Classes”,旨在保留C语言的所有功能并添加面向对象的特性。随着...

    C++期末复习--2.练习题_填空汇总.docx

    9. 当执行`cin`语句时,从键盘上输入每个数据后必须接着输入一个换行符('\n')才能继续输入下一个数据。 10. 重载一个函数的条件是:该函数必须在参数的个数或参数的类型上与其它同名函数有所不同。 11. 如果一个...

    数据结构代码

    在这个问题中,人们按顺时针方向从1开始报数,每数到m的人就会出局,然后从下一个人继续开始报数。程序的目标是找到最后一个留在圈中的人的编号。 3. **C++编程** 实现约瑟夫问题的代码使用了C++语言,包括结构体...

    2019重大复试之C++真题1

    9. **模板**:模板是C++中的泛型编程工具,可以用于创建类(类模板)或函数(函数模板)。`template&lt;class T&gt;`中的`T`是类型参数,代表任意数据类型。 10. **运算符重载的实现**:当运算符重载为类的成员函数时,`...

    华为面试笔试题很好的东东

    - C++模板允许创建泛型代码,适用于多种类型,提高了代码的重用性和灵活性,同时在编译时确保类型安全,并有助于跨平台的代码移植。 以上内容反映了华为面试笔试题中涵盖的关键C++概念,这些知识对于任何想要在IT...

    C++编程基础教程.docx

    - 兼备高级语言的结构和编程环境,同时拥有类似低级语言(如汇编语言)的系统资源操纵能力。 - 目标代码的执行效率仅略低于汇编语言,比大多数其他高级语言高。 - 丰富的运算符、数据类型和表达式,适用于各种...

    2009-2011腾讯校园招聘笔试题总结

    - 模板类允许创建泛型代码,适应多种数据类型,增强了代码的重用性和灵活性。 - 支持泛型算法,如容器和迭代器,使得算法独立于具体的数据类型。 - 提供了类型无关的容器和函数,例如C++标准库中的`std::vector`...

    C++CLI是连通C++与NET的桥梁PPT格式

    5. **泛型与模板集成**:C++/CLI提供了与.NET泛型的交互,虽然.NET泛型仅适用于托管类型,而C++模板可以应用于托管和非托管类型,两者结合提供了更大的灵活性。 6. **大型框架集成**:C++/CLI能够利用.NET ...

    网上转摘的华为笔试题目及答案

    - **模板与泛型编程**:C++支持模板机制,允许编写泛型代码,使得程序员可以编写可复用且高效的代码。 - **类与对象**:C++提供了面向对象编程的支持,允许定义类和创建对象,支持封装、继承和多态等特性。 - **...

    简述c++ 发展史

    从面向过程到面向对象,再到泛型和元编程,C++的每一步都体现了程序员对效率、灵活性和抽象层次的追求。随着C++20及以后版本的发布,C++将继续在软件开发领域扮演关键角色,提供强大而灵活的工具,服务于各种复杂的...

Global site tag (gtag.js) - Google Analytics