0%

  • Template Method
    • 特点:

      • 稳定的机构,但是子步骤有很多改变的需求。
      • 或者由于固有原因导致无法和任务的整体结构同时实现
    • 目的:

      在稳定结构的前提下,灵活实现变化或者晚期再来实现需求

Read more »

  • 依赖倒置原则(DIP)
    • 高层模块(稳定) 不应该依赖底层模块(不稳定),二者都应该依赖于抽象(稳定)
    • 抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)
  • 开放封闭原则(OCP)
    • 对扩展开放
    • 对更改封闭
  • 单一职责原则(SRP)
    • 一个类应该仅有一个引起他变化的原因
    • 变化的方向隐含着类的责任
  • Liskov 替换原则(LSP)
    • 子类必须能够替换他的基类(is-a)
    • 继承表达类型抽象
  • 接口隔离原则(ISP)
    • 接口小而完备
    • 不应该强迫客户依赖他们不用的方法
      Read more »

右值引用(Rvalue)

可以大幅改善容器的性能
当对象内部含有指针时,可以使用右值来窃取对象

原理

当右边的对象是一个右值时,左侧的对象可以偷取右侧对象的资源

1
2
3
4
//c11之前不可以对右值取地址
int x=foo()
int* p=&foo()//Error :对函数的返回值取地址
foo()=7;//Error:对函数的返回值复制
Read more »

  • decltype
    1
    2
    map<string,float> coll;
    decltype(coll)::value_type elem; // map<string,float>::value ele;
  • lambdas
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //mutable 关键字,表示是否可以改写
    //thorwSpec 表示可以抛出的异常
    //retType 表示返回值
    //三个都没有(parameters)可以不写
    // ^
    //[] 这个里面可以放外部的变量,不放入就看不见。可以传值和引用
    [...](parameters)mutable(opt),thorwSpec(opt)->retType(opt){
    ...
    }

    auto i=[...](parameters)mutable(opt),thorwSpec(opt)->retType(opt){
    ...
    }()//表示直接调用
    Read more »

  • Type ALias (与typedef 相似)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    //**************************//
    //type alias,identical to
    //typedef void(*func)(int,int);
    using func=void(*)(int,int);
    //func 表示一个入参为(int,int)类型的函数指针
    void example(int,int){}
    func fn=example;
    typdef basic_string<char> string;

    //**************************//
    //局部的typedef
    template<typename T>
    struct Container{
    using value_type=T;//typedef T value_type
    }
    //并且可以应用到原编程,如果上述定义了value_type
    template<typename Cntr>
    void fn2(const Cntr& c){
    typename Cntr::value_type n;
    }

    //**************************//
    //用于隐藏模板参数
    template<class CharT> using mystring=std::basic_string<CharT,std::char_traits<Chart>>
    mystring<char> str;
  • nonexcep
    1
    2
    void foo()noexcep;
    //void foo()noexcept(true); 表示不会抛出异常
Read more »

  • default&delete
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Zoo{
    public:
    //big five 可以运用到default,其它函数上会报错
    Zoo(int i1,int i2):d1(i1),d2(i2){}//构造函数
    Zoo(const Zoo&)=delete;//拷贝构造函数,不要这个函数,不可以使用
    Zoo(Zoo&&)=default;//右值引用,使用编译器默认的版本
    Zoo& operator=(const Zoo&)=default;//拷贝赋值
    Zoo& operator=(const Zoo&&)=delete;//移动赋值
    virtual ~Zoo(){};
    private:
    int d1,d2;
    };
  • alias Template
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    template <typename T>
    using Vec=std::vector<T,MyAlloc<T>>;
    Vec<int> coll;

    // 使用宏定义
    #define Vec<T> template<typename T> std::vector<T,MyAlloc<T>>;
    Vec<int> coll;
    //template<typename int> std::vector<int,MyAlloc<int>> 是这样的效果

    //使用typedef,因为typedef 不接收参数,只能使用如下所示
    typedef std::vector<int,MyAlloc<int>> Vec;
  • template template parameter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template<typename T,template<class> class Container>
//template<typename T,template<typename> class Container>
class XCIs
{
private:
Container<T> c;
public:
XCIs(){
for(long i=0;i<SIZE;i++){
c.insert(c.end(),T());
}
output_static_data(T());
Container<T> c1(c);
Container<T> c2(std::move(c));
c1.swap(c2);
}
}
Read more »

  • 一致初始化
    1
    2
    3
    4
    5
    6
    int values[]{1,2,3};
    vector<int> v{1,2,3,4,5};
    vector<string> cities{
    "Berlin","New York"
    }
    complex<double> c{3.0,4.0}
  • initializer_list
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    //***********************//
    //initializer_list 传递的是引用,拷贝是浅拷贝
    //***********************//

    {1,2,3}// 会被编译器构造成一个initializer_list
    //如果函数只接收initializer_list 则调用者要自己准备一包initializer_list,来使用
    //如果目标函数不接受initializer_list,会被编译器分开来传入
    int i;//i的值是未定义
    int j{};//设置初值为0
    int* p;//未定义初值
    int* q{};//设置初值为nullptr
    int x1(5.3); // x1=5
    int x2 = 5.3;//x2=5
    int x3{5.0};//Error:narrowing ||-> GCC Warning
    int x4 ={5.3}; // Error:narrowing ||-> GCC Warning
    char c1{7};//ok
    char c2{99999};//Error:narrowing ||-> GCC Warning
    std::vector<int> v1{1,2,3,4,5};//ok
    std::vector<int> v1{1,2,3,4,5.5};//Error:narrowing ||-> GCC Warning

    max({stirng("Ace"),string("Stacy"),stirng("qqq"),string("ppp")}) //函数可以接收initializer_list,作为入参
    min({1,2,3,4})//函数可以接收initializer_list,作为入参
    Read more »

  • class Template

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    template<typename T>
    class complex
    {
    public:
    complex(T r=0;T i=0):re(r),im(i){}
    complex& operator +=(const complex&);
    T real()const{return re;}
    T imag()const{return im;}
    private:
    T re,im;
    friend complex& __doapl(complex*, const complex)
    }
    {
    complex<double> c1(2.5,1.4);
    complex<int> c2(2,6);
    }
  • 函数模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    template<class T> //class 可以换位typename
    inline
    const T& min(const T&a,const T&b){
    return b<a ? b:a;
    }

    * 成员模板

    ```cpp
    template <class T1,class T2>
    struct pair{
    ...
    T1 first;
    T2 second;
    pair():first(T1()),second(T2()){}
    pair(const T1& a,const T2& b):first(a),second(b){}

    template <class U1,class U2>
    pair(const pair<U1,U2>& p):first(p.first),second(p.second){}
    }

    <!-- more -->
    # class Template
    ```cpp
    template<typename T>
    class complex
    {
    public:
    complex(T r=0;T i=0):re(r),im(i){}
    complex& operator +=(const complex&);
    T real()const{return re;}
    T imag()const{return im;}
    private:
    T re,im;
    friend complex& __doapl(complex*, const complex)
    }
    {
    complex<double> c1(2.5,1.4);
    complex<int> c2(2,6);
    }

function Template

函数模板不用指明类型

1
2
3
4
5
6
7
8
template<class T> //class 可以换位typename
inline
const T& min(const T&a,const T&b){
return b<a ? b:a;
}


// 如果是类对象要看对象是否重载了操作符<

成员模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <class T1,class T2>
struct pair{
...
T1 first;
T2 second;
pair():first(T1()),second(T2()){}
pair(const T1& a,const T2& b):first(a),second(b){}

template <class U1,class U2>
pair(const pair<U1,U2>& p):first(p.first),second(p.second){}
}

class Base1{};
class Derived1:public Base1{};

class Base2{};
class Dervied2:public Base2{};

// T1 ,T2 U1 , U2
pair<Base1,Base2> p2(pair<Dervied1,Derived2>());

例子

1
2
3
4
5
6
7
8
9
template <typename>
class shared_prt:public __share_ptr<_Tp>{
...
template<typename _Tp1>
explicit shared_ptr(_Tp1 __p):__shared_ptr<_Tp>(__p){}
}

Base1* prt=new Derived; // up-cast
shared_ptr<Base1> sptr(new Derived1);// 模拟 up-cast

特化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <class Key>
struct has{}

template<>
struct hash<char>{
size_t operator()(char x)const {return x;}
};

template<>
struct hash<int>{
size_t operator()(int x)const {return x;}
};

template<>
struct hash<long>{
size_t operator()(long x)const {return x;}
}

偏特化

  • 个数的偏特化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //从左向右特化,个数的特化,只有一个模板参数
    template <typename T,typename Alloc=...>
    class Vector{

    }

    template <typename Alloc=...>
    class vector<bool,Alloc>{

    }
  • 范围上的偏

1
2
3
4
5
6
7
8
9
10
11
12
template <typename T>
class C{

}
//指定是指针
template <typename T>
class C<T*>{

}

C<string> obj1;
C<string*> obj2;

模板模板参数(template template parameter)

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<template T ,template<typename T> class Container> //template<template T ,template<class T> class Container> 
class XCls{
private:
Container<T> c; //用第一个模板参数做参数
public:
....;
}

template<typename T>
using Lst = list<T,allocator<T>>;//别名

XCls<string, list> mylst1;//Error 默认模板的第二参数,

XCls<string, Lst> mylst1;//


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<template T ,template<typename T> class SmartPtr> //template<template T ,template<class T> class Container> 
class XCls{
private:
SmartPtr<T> c; //用第一个模板参数做参数
public:
XCls():sp(new T){}
}

template<typename T>
using Lst = list<T,allocator<T>>;//别名

XCls<string, list> mylst1;//Error 默认模板的第二参数,

XCls<string, Lst> mylst1;//

XCls<string,shared_ptr> p1;
XCls<double,unique_ptr> p2; // Error
XCls<int,weak_ptr> p3;// Error
XCls<int,auto_ptr> p4;

是否是模板模板参数

1
2
3
4
5
6
7
8
9
10
11
12
template <class T,class Sequence = deque<T>>
class stack{
friend bool operator == <> (const stack&,const stack)
friend bool operator < <> (const stack&,const stack)

protect:
Sequence c;
}


stack<int> s1;
stack<int,list<int>> s2; //没有模糊的地带了,是确定的。因此不是模板模板参数