[GeekBand][C++面向?qū)ο蟾呒?jí)編程]第四周學(xué)習(xí)筆記

本周開始進(jìn)入C++面向?qū)ο蟾呒?jí)編程(下)的課程中
內(nèi)容好散,寫得累死。

1. Conversion Function,轉(zhuǎn)換函數(shù)

在類需要轉(zhuǎn)換成為其它類型時(shí),需要設(shè)計(jì)轉(zhuǎn)換函數(shù)
函數(shù)簽名一般格式為:operator typename() const,無參數(shù),不用顯式寫出返回類型。

例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;   // 調(diào)用operator double()將 f 轉(zhuǎn)為 0.6

2.non-explicit-one-argument ctor

注:未加explicit修飾的單參數(shù)構(gòu)造函數(shù),如 例2 中Fraction類的構(gòu)造函數(shù)。

例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;  // 調(diào)用non-explicit ctor將 4 轉(zhuǎn)換為 Fraction(4, 1)
                    // 然后調(diào)用operator+

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

下面是兩種函數(shù)并存所導(dǎo)致的錯(cuò)誤情況,當(dāng)有多條路線可以達(dá)到目的時(shí),將導(dǎo)致歧義

例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關(guān)鍵字后,one-argument ctor將不能自動(dòng)轉(zhuǎn)換。

例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. 關(guān)于智能指針

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

例5:
template <typename T>

class shared_ptr
{
public:
    T& operator *() const
    {
        return *px;
    }

    T& operator ->() const
    {
        return px;
    }

private:
    T* px;
    long* pn;
……
};
!! 箭頭運(yùn)算符->是一種特殊的運(yùn)算符,它將一直向下作用,不會(huì)被消耗。
2. 關(guān)于迭代器

針對(duì)容器設(shè)計(jì)對(duì)應(yīng)的迭代器。

例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,所謂仿函數(shù)

指重載了函數(shù)調(diào)用運(yùn)算符()的類,使用時(shí)可以像調(diào)用函數(shù)一樣。

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

6. class template,類模版

將可變?cè)刈龀赡0妫褂迷撃0鏁r(shí)再與具體的類型進(jìn)行綁定。

例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,函數(shù)模版

又稱算法

例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);   // 編譯器會(huì)對(duì)function template進(jìn)行實(shí)參推導(dǎo)(argument deduction)

8. menber template,成員模版

類內(nèi)也可以設(shè)置成員模版。

例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,模版(全)特化

針對(duì)泛化編程中的某些情況可以設(shè)計(jì)特殊的算法,稱為模版特化。

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

10. partial specialization,模版偏特化

1. 個(gè)數(shù)的偏

例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,模版模版參數(shù)

將模版作為模版參數(shù)時(shí)使用。此時(shí)默認(rèn)模版參數(shù)必須顯式寫出。

例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;  // 錯(cuò)誤
XCls<string, Lst> mylst2;

12. Reference

Reference底層是利用指針實(shí)現(xiàn)的。(漂亮的指針)

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聲明,前提對(duì)象賦予默認(rèn)值。

例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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容