美文网首页
[GeekBand][C++面向对象高级编程]第四周学习笔记

[GeekBand][C++面向对象高级编程]第四周学习笔记

作者: 散夜霜 | 来源:发表于2017-02-11 23:14 被阅读0次

    本周开始进入C++面向对象高级编程(下)的课程中
    内容好散,写得累死。

    1. Conversion Function,转换函数

    在类需要转换成为其它类型时,需要设计转换函数
    函数签名一般格式为:operator typename() const,无参数,不用显式写出返回类型。

    例1:
    class Fraction
    {
    public:
        Fraction(int num, int den = 1)
            :m_numerator(num), m_denominator(den) {}
        operator double()   const
        {
            return double(m_numerator) / double(m_denominator);
        }
    
    private:
        int m_numerator;
        int m_denominator;
    };
    
    Fraction f(3, 5);
    double d = 4 + f;   // 调用operator double()将 f 转为 0.6
    

    2.non-explicit-one-argument ctor

    注:未加explicit修饰的单参数构造函数,如 例2 中Fraction类的构造函数。

    例2:
    class Fraction
    {
    public:
        Fraction(int num, int den = 1)
            :m_numerator(num), m_denominator(den) {}
        Fraction operator+(const Fraction& f)
        {
            return Fraction(……);
        }
    
    private:
        int m_numerator;
        int m_denominator;
    };
    
    Fraction f(3, 5);
    double d2 = f + 4;  // 调用non-explicit ctor将 4 转换为 Fraction(4, 1)
                        // 然后调用operator+
    

    !! conversion function vs. non-explicit-one-argument ctor

    下面是两种函数并存所导致的错误情况,当有多条路线可以达到目的时,将导致歧义

    例3:
    class Fraction
    {
    public:
        Fraction(int num, int den = 1)
            :m_numerator(num), m_denominator(den) {}
        operator double()   const
        {
            return double(m_numerator) / double(m_denominator);
        }
        Fraction operator+(const Fraction& f)
        {
            return Fraction(……);
        }
    
    private:
        int m_numerator;
        int m_denominator;
    };
    
    Fraction f(3, 5);
    Fraction d2 = f + 4;    // [Error]ambiguous
    

    3. explicit-one-argument ctor

    explicit关键字后,one-argument ctor将不能自动转换。

    例4:
    class Fraction
    {
    public:
        explicit Fraction(int num, int den = 1)
            :m_numerator(num), m_denominator(den) {}
        operator double()   const
        {
            return double(m_numerator) / double(m_denominator);
        }
        Fraction operator+(const Fraction& f)
        {
            return Fraction(……);
        }
    
    private:
        int m_numerator;
        int m_denominator;
    };
    
    Fraction f(3, 5);
    Fraction d2 = f + 4;    // [Error]conversion from 'double' to 'Fraction' requested
    

    4. pointer-like classes

    1. 关于智能指针

    智能指针的一般形式如下:

    例5:
    template <typename T>
    
    class shared_ptr
    {
    public:
        T& operator *() const
        {
            return *px;
        }
    
        T& operator ->() const
        {
            return px;
        }
    
    private:
        T* px;
        long* pn;
    ……
    };
    
    !! 箭头运算符->是一种特殊的运算符,它将一直向下作用,不会被消耗。
    2. 关于迭代器

    针对容器设计对应的迭代器。

    例6:
    template <typename T>
    struct __list_node
    {
        void* prev;
        void* next;
        T data;
    };
    
    template <typename T,typename Ref,typename Ptr>
    struct __list_iterator
    {
        typedef __list_iterator<T, Ref, Ptr> self;
        typedef Ptr pointer;
        typedef Ref reference;
        typedef __list_node<T>* link_type;
        link_type node;
        bool operator==(const self& x) const { return node == x.node; }
        bool operator!=(const self& x) const { return node != x.node; }
        reference operator*() const { return (*node).data; }
        pointer operator->() const { return &(operator*()); }
        self& operator++() { node = link_type((*node).next); return *this; }
        self operator++(int) { self tmp = *this; ++*this; return tmp; }
        self& operator--() { node = link_type((*node).prev); return *this; }
        self operator--(int) { self tmp = *this; --*this; return tmp; }
    };
    

    5. function-like classes,所谓仿函数

    指重载了函数调用运算符()的类,使用时可以像调用函数一样。

    例7:
    template <typename T>
    struct identity
    {
        const T& operator()(const T& x) const { return x }
    };
    

    6. class template,类模版

    将可变元素做成模版,使用该模版时再与具体的类型进行绑定。

    例8:
    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.5);
        complex<int> c2(2, 6);
        ……
    }
    

    7. function template,函数模版

    又称算法

    例9:
    template <typename T>
    inline const T& min(const T& a, const T& b)
    {
        return a < b ? b : a;
    }
    
    class stone
    {
    public:
        stone(int w, int h, int we)
            :_w(w), _h(h), _weight(we)
        {}
        bool operator <(const stone& rhs) const
        {
            return _weight < rhs._weight;
        }
    private:
        int _w, _h, _weight;
    };
    
    stone r1(2, 3), r2(3, 3), r3;
    r3 = min(r1, r2);   // 编译器会对function template进行实参推导(argument deduction)
    

    8. menber template,成员模版

    类内也可以设置成员模版。

    例10:
    template <typename T1, typename T2>
    struct pair
    {
        typedef T1 first_type;
        typedef T2 second_type;
    
        T1 first;
        T2 second;
    
        pair()
            :first(T1()), second(T2())
        {}
        pair(const T1& a, const T2& b)
            :first(a), second(b)
        {}
    
        template <typename U1, typename U2>
        pair(const pair<U1, U2>& p)
            : first(p.first), second(p.second)
        {}
    };
    

    9. (full) specialization,模版(全)特化

    针对泛化编程中的某些情况可以设计特殊的算法,称为模版特化。

    例11:
    template <typename Key>
    struct hash {};
    
    template <>
    struct hash<char>
    {
        size_t operator ()(char x) const { return x; }
    }
    

    10. partial specialization,模版偏特化

    1. 个数的偏

    例12:
    template <typename T, typename Alloc=……>
    class vector
    {
        …
    };
    
    template <typename Alloc = ……>
    class vector<bool, Alloc>
    {
        …
    };
    

    2. 范围的偏

    例13:
    template <typename T>
    class C
    {
        …
    };
    
    template <typename T>
    class C<T*>
    {
        …
    };
    
    C<string> obj1;
    C<string*> obj2;
    

    11. template template parameter,模版模版参数

    将模版作为模版参数时使用。此时默认模版参数必须显式写出。

    例14:
    template <typename T, template <typename T>class Container>
    class XCls
    {
    private:
        Container<T> c;
    public:
        ……
    };
    
    template <typename T>
    using Lst = list<T, allocator<T>>;
    
    XCls<string, list> mylst1;  // 错误
    XCls<string, Lst> mylst2;
    

    12. Reference

    Reference底层是利用指针实现的。(漂亮的指针)

    13. variadic templates (since C++11)

    拆包用,直接上例子。

    例15:
    void print()
    {
    }
    
    template <typename T,typename... Types>
    void print(const T& firstArg, const Types&... args)
    {
        cout << firstArg << endl;
        print(args...);
    }
    

    14. auto (since C++11)

    可以将auto作为typename声明,前提对象赋予默认值。

    例16:

    auto a = 0; // a是int

    15. ranged-base for (since C++11)

    格式如下

    for (delc : coll)
    {
        statement;
    }
    
    例17:
    vector<double> vec;
    …
    for (auto elem : vec)
    {
        cout << elem << endl;
    }
    
    for (auto& elem : vec)
    {
        elem *= 3;
    }
    

    相关文章

      网友评论

          本文标题:[GeekBand][C++面向对象高级编程]第四周学习笔记

          本文链接:https://www.haomeiwen.com/subject/cmeoittx.html