C++知识点随笔(六):模板

原创 2015年07月09日 13:59:29

一、函数模板

C++中模板和重载的区别:
模板是除了类型全都相同的情况下可以使用;而重载是里面的功能也有不同时使用的。
下面看一个函数模板的使用实例:

#include<iostream>
using namespace std;

typedef struct _Node
{
    int m_a;
    char* m_str;
}Node;

bool leftNodeBig(Node a, Node b) //结构体从大到小排
{
    return (a.m_a < b.m_a);
}

template <typename T>   //整形从大到小排
bool leftBig(T t, T w)
{
    return (t < w); 
}

template <typename T>   //整形从小到大排
bool leftSmall(T t, T w)
{
    return (t > w); 
}

template <typename T>
void Bubble(T* arr, int nLength, bool (*pFun)(T a, T b)) //注意函数指针格式
{
    for(int i=0;i<nLength-1;i++)
    {
        for (int j=0;j<nLength-1-i;j++)
        {
            if((*pFun)(arr[j], arr[j+1]))
            {
                //注意这里不能通过 ^ 交换了,因为结构体无法这样交换
                //arr[j] = arr[j] ^ arr[j+1]; 
                //arr[j+1] = arr[j] ^ arr[j+1];
                //arr[j] = arr[j] ^ arr[j+1];
                T temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

template <typename T>
void Show(T* arr, int nLength)
{
    for(int i=0;i<nLength;i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

ostream& operator<<(ostream& os, Node& node) //重载操作符保证结构体正常输出
{
    os << node.m_a << " " << node.m_str;
    return os;
}


int main()
{
    int arr[] = {1,3,5,7,9,0,8,6,4,2};
    Bubble(arr, 10, &leftBig<int>);
    Show(arr, 10);

    char str[] = {'b','e','f','y','s','a','c','d','l','z'};
    Bubble(str, 10, &leftSmall<char>);
    Show(str, 10);

    Node arrNode[] = {{10,"hehe"},{9,"haha"},{100,"yaya"}};
    Bubble(arrNode, 3, &leftNodeBig);
    Show(arrNode,3);

    system("pause");
    return 0;
}

二、类模板

类模板要注意:只要我们定义了类模板的 template,那么我们只要除了这个类,一见到这个类名,就要加:

CPeople<>

其实函数模板也是一样的,定义了函数模板之后,我们在外面使用这个函数的时候也要添加类型,不加同样会报错,就像我们上面写的:

Bubble(arr, 10, &leftBig<int>);

下面我们看一段类模板的使用实例:

#include<iostream>
using namespace std;

template<typename T>
class CPeople
{
public:
    //注意使用初始列表给成员变量初始化,因为我们传进来的模板T有可能是对象,前面我们也学习过,如果在类中定义一个有参数的类,那么一定要在初始化列表中给它传参。
    CPeople(T t):m_t(t) 
    {
    }
    virtual void Show() //虚函数,调用子类重写的 Show()
    {
        cout << this->m_t << endl;
    }
protected:
    T m_t;
};

template<typename P, typename Q>
class CChinese : public CPeople<Q>
{
public:
    CChinese(P p, Q q):CPeople<Q>(q), m_p(p) //这里一定要使用初始化列表
    {
    }
    void Show()
    {
        //如果我们不重载CAA类的‘<<’操作符的话,这一句就会报错
        cout << m_t << " " << this->m_p << endl;
    }
private:
    P m_p;
};

template<typename M>
class CAA
{
public:
    CAA(M m)
    {
        this->m_m = m;
    }
public:
    M m_m;
};

template<typename N>
ostream& operator<<(ostream& os, CAA<N>& aa)  //重载CAA类的操作符
{
    os << aa.m_m;
    return os;
}

int main()
{
    //父类指针指向子类对象,子类实现<double, char*>类型的模板
    CPeople<char*> *p1 = new CChinese<double, char*>(123.456, "hello");
    p1->Show();

    //父类指针指向子类对象,子类将对象作为模板
    CAA<double> caa(56.78);
    CPeople<CAA<double>> *p2 = new CChinese<double, CAA<double>>(123.456, caa);
    p2->Show();

    //父类指针指向子类对象,子类将两个对象作为模板
    CAA<char*> *cbb = new CAA<char*>("hello world!");
    CPeople<CAA<char*>> *p3 = new CChinese<CAA<double>,CAA<char*>>(caa, *cbb);
    p3->Show();

    system("pause");
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

C++知识点随笔(三):static、const、friend、inline

一、static静态成员属性为什么要在类外初始化? 静态成员属性之所以不能在构造函数内初始化,是因为构造函数必须要在定义对象的时候才会调用,而static变量在编译的时候就创建了,所以要在类外通过类...

C++知识点随笔(七):成员函数指针、模拟虚函数列表

成员函数指针普通的全局函数指针定义:typedef void (*PFUN)();普通的函数指针可以指向返回值和参数类型都相同的全局函数,可是成员函数该怎么办呢?如果成员函数是static的,那么可以...

C++知识点随笔(二):继承、多态

一、继承继承是类之间的,对象之间没有什么关系,比如子类继承了父类的成员属性,并且子类的对象修改了这个成员属性,可是修改之后我们再去输出父类的成员属性发现并没有发生改变,原因是这两个对象本来就是两块空间...

C++知识点随笔(五):虚继承

虚继承的出现就是为了解决多继承中访问不明确的问题。 首先让我们先看一下虚继承的代码:#include using namespace std;class AA { public: int m...

C++ 知识点(完):高级编程:模板,预处理器,信号处理,多线程,Web编程

模板模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。每个容器都有一个单...
  • Jurbo
  • Jurbo
  • 2016年09月08日 12:12
  • 2515

c++模板的一些知识点总结

一. 1 可以为类模板的模板参数提供默认参数,函数模板却不行。 2可以为类模板进行偏特化,而函数模板却不行。 二.模板参数 1 类型(可以是内建类型或是用户自定义类型) 2 无类型参数(整数...
  • lgp88
  • lgp88
  • 2011年12月08日 21:31
  • 1826

深度学习(DL)与卷积神经网络(CNN)学习笔记随笔-01-CNN基础知识点

转载自:http://blog.csdn.net/niuwei22007/article/details/47399913 《CNN基础知识点》From:Convolutional Neur...

深度学习(DL)与卷积神经网络(CNN)学习笔记随笔-01-CNN基础知识点

《CNN基础知识点》From:Convolutional Neural Networks (LeNet)原文链接可以查看更多信息:http://blog.csdn.net/niuwei22007/ar...

进程、线程知识点随笔

优先级反转问题 原理 所谓优先级翻转问题(priority inversion)即当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,而这个低优先级任务...

C/C++知识点总结(六)

52.函数对象提供了一种方法,将要调用的函数与准备传递给这个函数的隐式参数捆绑起来。 53.和在C中一样,C++不可能有函数类型的变量,所以任何声明这种变量的企图都将立即被转换成指向函数的指针声明。和...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++知识点随笔(六):模板
举报原因:
原因补充:

(最多只允许输入30个字)