C++类模板的总结

C++ 类模板

模板类是一个很有用的工具, 平常使用比较多的像std::vector, std::map, std::queue都是模板类, 可以说很方便. 但是背后的实现可以说是很复杂, 包括内存分配,包括快速访问. 我们之所以能这么方便的使用,全是站在了巨人的肩膀上.

模板定义的C++实体如下

  • 类模板,可以是嵌套类
  • 函数模板,可以是成员函数
  • 别名模板 (C++11 起)
  • 变量模板 (C++14 起)
  • requires 与 concept (C++20 起)

本文主要介绍类模板和函数模板, 首先我们定义一个模板类

template<class T>
class MyClass
{
public:
    MyClass(){};
    explicit MyClass(const T& src):vec_(src){}
    ~MyClass(){}
    const T& get_vec() const
    {
        return vec_;
    }
    MyClass<T>& operator+(const MyClass<T> r);
    MyClass<T>& operator=(const MyClass<T> r);

public:
    T vec_;
};

在这个类当中,我们定义了一个公有成员变量,这个变量可以被外部访问, 这个类可以作为一个基础类使用, 另外我们定义了两个构造函数和一个析构函数. 另外的函数包括返回成员的函数和两个操作符重载的函数;
接下来是关于类模板的实现了, 可以看到,这里面有一些内联函数,由于比较短, 写成内联的比较合适. 关于重载操作符的两个函数则在类外定义. 注意: 根据C++标准类模板的定义与实现都得在同一个.hpp文件里

template<class T> inline
MyClass<T>& MyClass<T>::operator=(const MyClass<T> r)
{
    this->vec_ = r.vec_;  //其中这里的this可以省略
    return *this;
}

template<class T> inline
MyClass<T>& MyClass<T>::operator+(const MyClass<T> r)
{
    this->vec_ = this->vec_ + r.vec_;//其中这里的this可以省略
    return *this;
}

模板类的用途大多数的时候是用在公用库里面, 供他人调用.这个类在逻辑上显得比较多余,但是可以拿来练手. 如果考虑将其实现为vector这样的类,那么得考虑动态内存分配, 考虑内存释放的问题,比较复杂.
另外多看优秀的源码可以帮我们提高代码能力, 如下面这段,我截取了 opencv里面的Rect_类的实现 ,即矩形的实现
Rect.hpp

template<typename _Tp> class Rect_
{
public:
    typedef _Tp value_type;

    //! default constructor
    Rect_();
    Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
    Rect_(const Rect_& r);
    Rect_(Rect_&& r);


    Rect_& operator = ( const Rect_& r );
    Rect_& operator = ( Rect_&& r );
    Rect_& operator + ( const Rect_& r);


    //! area (width*height) of the rectangle
    _Tp area() const;
    //! true if empty
    bool empty() const;

    _Tp x; //!< x coordinate of the top-left corner
    _Tp y; //!< y coordinate of the top-left corner
    _Tp width; //!< width of the rectangle
    _Tp height; //!< height of the rectangle
};


template<typename _Tp> inline
Rect_<_Tp>::Rect_():x(0), y(0), width(0), height(0){}

template<typename _Tp> inline
Rect_<_Tp>::Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height)
    : x(_x), y(_y), width(_width), height(_height){}

template<typename _Tp> inline
Rect_<_Tp>::Rect_(const Rect_& r)
    : x(r.x), y(r.y), width(r.width), height(r.height){}

template<typename _Tp> inline
Rect_<_Tp>::Rect_(Rect_&& r)
    : x(std::move(r.x)), y(std::move(r.y)), width(std::move(r.width)), height(std::move(r.height)){}

template<typename _Tp> inline
Rect_<_Tp>& Rect_<_Tp>::operator=(const Rect_<_Tp>& r)
{
    x = r.x;
    y = r.y;
    width = r.width;
    height = r.height;
    return *this;
}

template<typename _Tp> inline
Rect_<_Tp>& Rect_<_Tp>::operator=( Rect_<_Tp>&& r)
{
    x = std::move(r.x);
    y = std::move(r.y);
    width = std::move(r.width);
    height = std::move(r.height);
    return *this;
}
template<typename _Tp> inline
Rect_<_Tp>& Rect_<_Tp>::operator+( const Rect_<_Tp>& r)
{
    x = r.x;
    y = r.y;
    width = r.width;
    height = r.height;
    return *this;
}


template<typename _Tp> inline
_Tp Rect_<_Tp>::area() const
{
    return width*height;
}
template<typename _Tp> inline
bool Rect_<_Tp>::empty() const
{
    return width <=0 || height <= 0;
}

注意:不要在.hpp文件中使用using namespace std这样的代码,很容易造成命名空间污染
Rect_类的实现,作为opencv的一个基础类型,使用场合还是很多的,可以看到他的构造函数比较丰富,而且我还删除了其中的一些和Point_类的相关的构造函数, 和成员函数. 另外我加了一个+号的操作符重载函数, 逻辑上来讲, 两个矩形相加的操作没太大意义
最后放上main函数

#include <iostream>
#include <string>
#include "MyClass.hpp"
#include "Rect.hpp"
using namespace std;
int main(int argc, char* argv[])
{

    string vs ="blackshake";
    string vp = "_hahha";

    MyClass<string> myc(vs);

    MyClass<string> r(vp);
    myc = myc+r;

    string str = myc.get_vec();
    cout<<str;

    Rect_<int> rect1(100, 35, 100, 200);
    Rect_<int> rect2(rect1);

    cout<<rect1.area();
    cout<<rect1.empty();  
      
    return 0;
}

通过多看源码,可以学习别人的优秀技巧!

																2020.01.17	--Zlatan
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值