一、conversion function; 一開始想在網上找一找關于conversion function的信息,但是只有在MSDN上找到只言片語: https://msdn.microsoft.com/en-us/library/5s5sk305.aspx This content has been relocated. For information about conversion functions, see User-Defined Type Conversions (C++). 好吧巨硬你贏了。 還是從侯捷老師的程序開始講起吧。
class Fraction{public: Fraction(int num, int den = 1):m_numerator(num), m_denominator(den) {} Operator double() const { return (double) (m_numberator / m_denominator); }PRivate: int m_numerator; int m_denominator;}當程序運行如下時:
Fraction f(3,5);double d = 4 + f;如果沒有定義
friend Fraction operator+(const double &lhs,const Fraction &rhs)那么在一般意義上,+號會報錯。 但是在類Fraction中有:
operator double() const{}這個函數,意味著它可以在需要的時候,將類Fraction的實例轉double。
從另一個方向來說:
class Fraction{public: Fraction(int num, int den = 1):m_numerator(num), m_denominator(den) {} Fraction operator+(const Fraction &rhs){}private: int m_numerator; int m_denominator;}此時運行
Fraction d2 = f + 4;會調用構造函數,將4轉化為Fraction(4,1),然后調用Fracion operator+。
然而當Fraction(),operator+,operator double()同時存在時,再次調用就會出現二義性,編譯器無法分辨到底應該調用哪一個函數。但是這幾個函數都是有必要存在的,怎么辦? 此時可以在 Fraction()前加上explicit 修飾詞,此時,此構造函數不可以用于隱式地創建Fraction對象。 關鍵字只對一個實參的構造函數有效,需要多個構造函數不能用于執行隱式轉換,所以無需將這些構造函數指定為explicit的。 當我們用explicit關鍵字聲明構造函數時,它將只能以直接初始化的形式使用,而且編譯器不會在自動轉換中使用該構造函數。
二、智能指針: 智能指針類似于vector,它也是一個模板,讓我們創建一個只能指針時,也必須提供額外的信息—-指針指向的類型。默認初始化的智能指針中保存著一個空指針。 由于智能指針只是一個模板類,所以需要重載’*’與’->’來達到與指針相似的用法,
T& operator*() const{}T& operator->() const {}關于*運算符的重載,大家應該都沒有什么異議,關于->運算符重載大家肯定由疑問。 比如程序如下:
shared_ptr<Foo> sp (new Foo);sp->method();此時由于(sp->)method()調用運算符重載,那么不會變成(ptr)methon()這種類型么? 群友在 https://www.ibm.com/support/knowledgecenter/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/language_ref/cplr329.html 找到了解答。
The statement x->f() is interpreted as (x.operator->())->f().
The operator-> is used (often in conjunction with the pointer-dereference operator) to implement “smart pointers.” These pointers are objects that behave like normal pointers except they perform other tasks when you access an object through them, such as automatic object deletion (either when the pointer is destroyed, or the pointer is used to point to another object), or reference counting (counting the number of smart pointers that point to the same object, then automatically deleting the object when that count reaches zero).
這個是C++中約定俗稱的一種語法,這個鍋主要還是要甩給’.’運算符無法進行重載,所以給’->’一個特殊的重載形式。
三、迭代器:
An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).
The most obvious form of iterator is a pointer: A pointer can point to elements in an array, and can iterate through them using the increment operator (++). But other kinds of iterators are possible. For example, each container type (such as a list) has a specific iterator type designed to iterate through its elements.
Notice that while a pointer is a form of iterator, not all iterators have the same functionality of pointers; Depending on the properties supported by iterators, they are classified into five different
迭代器是一個類,但是它歸根究底,還是用指針實現的。比較簡單,并沒有什么好講的。
四、仿函數: 其實它的本質就是一個重載了()運算符的類。
// this is a functorstruct add_x { add_x(int x) : x(x) {} int operator()(int y) const { return x + y; }private: int x;};// Now you can use it like this:add_x add42(42); // create an instance of the functor classint i = add42(8); // and "call" itassert(i == 50); // and it added 42 to its argumentstd::vector<int> in; // assume this contains a bunch of values)std::vector<int> out(in.size());// Pass a functor to std::transform, which calls the functor on every element // in the input sequence, and stores the result to the output sequencestd::transform(in.begin(), in.end(), out.begin(), add_x(1)); assert(out[i] == in[i] + 1); // for all i五、模板: 模板是c++泛型編程的基礎,一個模板就是創建類或者函數的藍圖或者說公式。 一個函數模板就是一個公式,可以用來生成針對特定類型的函數的版本。
類模板同理,但是類模板不能一依靠編譯器為類模板推斷參數類型,我們必須在模板名后的<>內提供額外信息,用來代替模板參數的實參列表,編譯器用這些模板實參來實例化特定的類。
模板的參數遵循普通的作用域原則,一個模板參數的名字的可用范圍是在其聲明之后,至模板參數定義結束之前。在模板內不可以重用模板參數名。 與函數中類似,聲明中的模板參數的名字不用與定義中相同。
一個類可以包含本身是模板的成員函數。這種函數稱為成員模板。
為了實例化一個類函數的成員模板,我們必須同時提供類和函數模板的實參。
六、模板模板參數: 主要優點在于:借助于某個依賴于模板參數的類型,就很容易讓類模板攜帶一些狀態信息(也就是靜態成員變量)。
在使用模板模板參數時,需要注意
cCls<string, list> mylist1;出錯的原因在于list模板其實有兩個模板參數。 如果想要寫成上面這種形式,要不就用using或者typedef將其轉化為類型別名,要不就將template<>內的模板參數與實際傳入的相匹配。
新聞熱點
疑難解答
圖片精選