在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    C++運算符重載為成員函數和非成員函數的限制

    我們知道,基本數據類型定義包括:

    值域或需要的內存空間;

    ② 位模式與編碼方案;

    ③ 可以適用的操作(能夠使用的運算符);

    例如double類型,使用8個字節(jié)的內存空間,使用IEEE754的編譯方案(1個符號位,11個指數位使用移碼,52個小數位),double可以使用+-*/等運算符,但不能使用模運算符%。

    一個操作符的運算可以理解為一個函數形式:

    a+b;operator+(a,b);

    自然,如果類類型要使用運算符,需要明確定義操作符操作數據成員的邏輯(也就是重載操作符),否則,會出現編譯錯誤。

    需要注意的是,運算符(operator)重載要求必須至少有一個類類型參數(或兩個類類型參數),如果參數一個都不是類類型,則也就沒有必要重載。對于第一個操作數(operand,出現在操作符的左邊)的類型也是有限制的。

    例如運算符[]要求第一個操作數只能是類對象,所以需要重載[]為成員函數(其第一個參數是隱含的this指針,指向類對象)。

    運算符<<要求第一個操作數為std::ostream類型對象,所以不能重載為成員函數,可以重載為友元函數。

    1 重載雙目運算符[]為成員函數

    雙目運算符[]限制了第一個參數必須為類類型,所以要重載為成員函數(第一個參數為類類型指針this)。

    #include class IntList{private: int m_list[10]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // give this class some initial state for this examplepublic: int& operator[] (int index); int operator[] (int index) const; // could also return const int& // if returning a non-fundamental type, use as a const argument};int& IntList::operator[] (int index) // for non-const objects: can be used for assignment{ return m_list[index];}int IntList::operator[] (int index) const // for const objects: can only be used for access{ return m_list[index];}int main(){ IntList list{}; list[2] = 3; // okay: calls non-const version of operator[] std::cout << list[2] << ''; const IntList clist{}; clist[2] = 3; // compile error: calls const version of operator[], which returns by value. Cannot assign to this because it is an rvalue. std::cout << clist[2] << ''; return 0;}

    2 重載雙目運算符<<為友元函數

    雙目運算符<<的第一個參數必須為std::ostream類型對象,為避免第一個對象為this指針,所以要避免重載為成員函數,可以重載為友元函數。

    #include class Point{private: double m_x {}, m_y {}, m_z {};public: Point(double x=0.0, double y=0.0, double z=0.0) : m_x { x }, m_y { y }, m_z { z } { } friend std::ostream& operator<< (std::ostream &out, const Point &point);};std::ostream& operator<< (std::ostream &out, const Point &point){ // Since operator<< is a friend of the Point class, we can access Point's members directly. out << "Point(" << point.m_x << ", " << point.m_y << ", " << point.m_z << ")"; return out;}int main(){ Point point1 { 2.0, 3.0, 4.0 }; std::cout << point1; return 0;}

    3 重載單目運算符++、–為成員函數

    class Digit{private: int m_digit;public: Digit(int digit=0) : m_digit{digit} { } Digit& operator++(); // prefix has no parameter Digit& operator–(); // prefix has no parameter Digit operator++(int); // postfix has an int parameter Digit operator–(int); // postfix has an int parameter friend std::ostream& operator<< (std::ostream& out, const Digit& d);};// No parameter means this is prefix operator++Digit& Digit::operator++(){ // If our number is already at 9, wrap around to 0 if (m_digit == 9) m_digit = 0; // otherwise just increment to next number else ++m_digit; return *this;}// No parameter means this is prefix operator–Digit& Digit::operator–(){ // If our number is already at 0, wrap around to 9 if (m_digit == 0) m_digit = 9; // otherwise just decrement to next number else –m_digit; return *this;}// int parameter means this is postfix operator++Digit Digit::operator++(int){ // Create a temporary variable with our current digit Digit temp{*this}; // Use prefix operator to increment this digit ++(*this); // apply operator // return temporary result return temp; // return saved state}// int parameter means this is postfix operator–Digit Digit::operator–(int){ // Create a temporary variable with our current digit Digit temp{*this}; // Use prefix operator to decrement this digit –(*this); // apply operator // return temporary result return temp; // return saved state}std::ostream& operator<< (std::ostream& out, const Digit& d){out << d.m_digit;return out;}int main(){ Digit digit(5); std::cout << digit; std::cout << ++digit; // calls Digit::operator++(); std::cout << digit++; // calls Digit::operator++(int); std::cout << digit; std::cout << –digit; // calls Digit::operator–(); std::cout << digit–; // calls Digit::operator–(int); std::cout << digit; return 0;}

    4 重載函數調用符()為成員函數

    #include class Accumulator{private: int m_counter{ 0 };public: int operator() (int i) { return (m_counter += i); }};int main(){ Accumulator acc{}; std::cout << acc(10) << ''; // prints 10 std::cout << acc(20) << ''; // prints 30 return 0;}

    You may wonder why we couldn’t do the same thing with a normal function and a static local variable to preserve data between function calls. We could, but because functions only have one global instance, we’d be limited to using it for one thing at a time. With functors, we can instantiate as many separate functor objects as we need and use them all simultaneously.

    您可能想知道為什么我們不能用普通函數和靜態(tài)局部變量來保存函數調用之間的數據。我們可以,但因為函數只有一個全局實例,所以我們只能一次使用一個實例。使用函數對象,我們可以根據需要實例化任意多個單獨的函數對象,并同時使用它們。

    Operator() is sometimes overloaded with two parameters to index multidimensional arrays, or to retrieve a subset of a one dimensional array (with the two parameters defining the subset to return). Anything else is probably better written as a member function with a more descriptive name.

    操作符()有時會重載兩個參數來索引多維數組,或檢索一維數組的子集(兩個參數定義要返回的子集)。其他任何內容都最好用更具描述性的名稱作為成員函數編寫。

    5 重載賦值運算符=為成員函數

    MyString& MyString::operator= (const MyString& str){// self-assignment checkif (this == &str)return *this;// if data exists in the current string, delete itif (m_data) delete[] m_data;m_length = str.m_length;// copy the data from str to the implicit objectm_data = new char[str.m_length];for (int i { 0 }; i < str.m_length; ++i)m_data[i] = str.m_data[i];// return the existing object so we can chain this operatorreturn *this;}

    6 When to use a normal, friend, or member function overload

    何時使用普通、友元或成員函數重載

    In most cases, the language leaves it up to you to determine whether you want to use the normal/friend or member function version of the overload. However, one of the two is usually a better choice than the other.

    在大多數情況下,該語言將由您決定是否要使用重載的普通/友元或成員函數版本。然而,兩者中的一個通常比另一個更好。

    When dealing with binary operators that don’t modify the left operand (e.g. operator+), the normal or friend function version is typically preferred, because it works for all parameter types (even when the left operand isn’t a class object, or is a class that is not modifiable). The normal or friend function version has the added benefit of “symmetry”, as all operands become explicit parameters (instead of the left operand becoming *this and the right operand becoming an explicit parameter).

    處理不修改左操作數的二元運算符(例如運算符+)時,通常首選普通或友元函數版本,因為它適用于所有參數類型(即使左操作數不是類對象,或是不可修改的類)。普通或友元函數版本具有“對稱”的額外好處,因為所有操作數都成為顯式參數(而不是左操作數變成*this,右操作數變成顯式參數)。

    When dealing with binary operators that do modify the left operand (e.g. operator+=), the member function version is typically preferred. In these cases, the leftmost operand will always be a class type, and having the object being modified become the one pointed to by *this is natural. Because the rightmost operand becomes an explicit parameter, there’s no confusion over who is getting modified and who is getting evaluated.

    處理確實修改左操作數的二進制運算符(例如運算符+=)時,通常首選成員函數版本。在這些情況下,最左邊的操作數將始終是類類型,并且將要修改的對象變?yōu)?所指的對象是很自然的。因為最右邊的操作數成為顯式參數,所以對于誰要修改誰來求值沒有任何混淆。

    Unary operators are usually overloaded as member functions as well, since the member version has no parameters.

    一元運算符通常也作為成員函數重載,因為成員版本沒有參數。

    The following rules of thumb can help you determine which form is best for a given situation:

    以下經驗法則可以幫助您確定哪種形式最適合特定情況:

    If you’re overloading assignment (=), subscript ([]), function call (()), or member selection (->), do so as a member function.

    如果要重載賦值(=)、下標([])、函數調用(())或成員選擇(->),請作為成員函數進行重載。

    If you’re overloading a unary operator, do so as a member function.

    如果要重載一元運算符,請作為成員函數進行重載。

    If you’re overloading a binary operator that does not modify its left operand (e.g. operator+), do so as a normal function (preferred) or friend function.

    如果要重載不修改其左操作數的二元運算符(例如運算符+),請將其作為普通函數(首選)或友元函數進行重載。

    If you’re overloading a binary operator that modifies its left operand, but you can’t add members to the class definition of the left operand (e.g. operator<<, which has a left operand of type ostream), do so as a normal function (preferred) or friend function.

    如果要重載修改其左操作數的二元運算符,但不能將成員添加到左操作數的類定義中(例如運算符<<,其左操作數類型為ostream),請將其作為普通函數(首選)或友元函數。

    If you’re overloading a binary operator that modifies its left operand (e.g. operator+=), and you can modify the definition of the left operand, do so as a member function.

    如果要重載修改其左操作數的二元運算符(例如運算符+=),并且可以修改左操作數的定義,請作為成員函數進行修改。

    -End-

    鄭重聲明:本文內容及圖片均整理自互聯網,不代表本站立場,版權歸原作者所有,如有侵權請聯系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月16日 18:17
    下一篇 2022年6月16日 18:17

    相關推薦

    • 存儲過程語法(sql server存儲過程語法)

      今天小編給各位分享存儲過程語法的知識,其中也會對sql server存儲過程語法進行解釋,如果能碰巧解決你現在面臨的問題,別忘了關注本站,現在開始吧! oracle存儲過程基本語法…

      2022年11月26日
    • 淘寶直播開通后帶貨鏈接怎么做(淘寶直播需要開通淘寶店鋪嗎)

      直播帶貨無論是對于商家來說還是主播收益都是非??捎^的,所以不少平臺都有直播帶貨功能,一些小伙伴也想加入淘寶直播,那么淘寶直播開通后帶貨鏈接怎么做?下面小編為大家?guī)硖詫氈辈ラ_通后帶…

      2022年11月24日
    • 銳龍97900x參數規(guī)格跑分評測 銳龍97900x屬于什么檔次

      銳龍9 7900X是銳龍7000系列處理器中性能頂尖的型號之一,它采用了這一代標配的zen4架構和5nm制程工藝,那么它具體的參數跑分如何,在電腦上世紀發(fā)揮怎么樣呢,下面就來看看銳…

      2022年11月24日
    • 1千克等于多少磅

      克,此定義在1958年被美國以及其他英聯邦會員國承認換算回來,一千克等于262磅,一磅等于037千克英國在1963年開始,依據度量衡法案的規(guī);1 磅=16 盎司=04536 千克 …

      2022年11月24日
    • vivox90pro配置參數跑分詳情 vivox90pro是什么屏幕

      vivox90pro參數配置詳情怎么樣?vivo手機在昨晚舉行了X90系列發(fā)布會,有普通款、pro款以及pro+款三個版本,那么vivox90pro具體配置怎么樣呢?下面就讓小編為…

      2022年11月23日
    • vivox90參數配置詳情 vivox90處理器功耗跑分介紹

      vivox90參數配置詳情怎么樣?vivo手機在昨晚舉行了X90系列發(fā)布會,有普通款、pro款以及pro+款三個版本,那么vivox90具體配置怎么樣呢?下面就讓小編為大家介紹一下…

      2022年11月23日
    • 快手限流多久能解除(快手限流什么意思)

      我相信很多人都看中了快手平臺的商機,都爭先恐后地想要搶占機會,可一些人剛剛作出一點成績,就被降權了,自己也不知道什么原因。所以今天就來聊聊快手賬號降權操作分享,趕快來看看避免違規(guī)!…

      2022年11月23日
    • Win11 22H2再出新問題Bug:無法彈出USB設備

      作為Windows 11的首次大更新,在Win11 22H2發(fā)布后并沒有帶來預想的場景,各種問題頻現成為了一種常態(tài)。 近日有消息稱,Win11 22H2存在一個占用沖突Bug,當用…

      2022年11月22日
    • 美團月付300小額取現?美團月付取現300不見了

      很多上班族每天都在使用美團點外賣,你知道美團現在推出了一款類似花唄的產品嗎?可以在美團消費的時候先消費后還款,叫做美團月付,是美團推出的一款消費型產品,不能直接提現到銀行卡,只能用…

      2022年11月21日
    • 京東店鋪類型有哪些京東入駐有什么資質要求

      今天的互聯網發(fā)展迅速,讓傳統(tǒng)企業(yè)有了更多選擇,但也同樣也對剛觸網的商家增添了許多迷茫,近日知舟電商就收到很多商家朋友詢問京東入駐相關問題,今天知舟君就給大家分享下。 一.京東入駐準…

      2022年11月18日

    聯系我們

    聯系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息