欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++20引入的三路比較操作符<=>

 更新時間:2025年06月27日 10:51:14   作者:洞陽  
本文主要介紹了c++20引入的三路比較操作符<=>,返回strong_ordering、weak_ordering和partial_ordering三種類型,下面就來具體介紹一下,感興趣的可以了解一下

一、簡介

c++20引入了三路比較操作符(或者三向比較)<=>(three-way comparison operator),也叫太空船(spaceship)操作符。

<=>也是一個二元關系運算符,但它不像其他二元比較操作符那樣返回類型是布爾類型,而是根據(jù)用戶指明的三種類型之一:partial_ordering、weak_ordering和strong_ordering,定義于標準庫頭文件<compare>中,默認為strong_ordering類型。

  • 偏序partial_ordering表達了比較關系中的偏序關系,即給定類的任意兩個對象不一定可比較。例如給定一棵對象樹,假設父節(jié)點比子節(jié)點大,<=>得到的結果將為greater,但不是任意兩個節(jié)點都可比較,此時它們的關系為unordered。對于偏序關系的排序,使用拓撲排序算法將獲得正確的結果。
  • 弱序weak_ordering表達了比較關系中的全序關系,即給定類的任意兩個對象都能比較,將既不大于也不小于的關系定義為等價(equivalent)關系。假設長方形類按照面積比較就是弱序關系,長寬分別為2和6的矩形與長寬分別為3和4的比較,面積都為12(既不大于也不小于)?,那么它們是等價的,但不相等是因為可以通過長寬區(qū)分出來它們不一樣。標準庫中的std::sort要求關系至少為弱序的才能正確工作。
  • 強序strong_ordering與弱序一樣,當對等價關系進行了約束即為相等(equal)關系??紤]正方形類按照面積比較就是強序關系,因為面積一樣的正方形無法像長方形那樣通過外表能區(qū)分出來,即它們是相等的。一些查找算法要求關系為強序才能正確工作。

此外<=>的結果也與字符串比較函數(shù)strcmp類似,能夠通過正負判斷關系:當結果大于0表示大于關系,等于0表示等價、等于關系,小于0表示小于關系。

顧名思義,三向比較就是在形如lhs <=> rhs的表達式中,兩個比較的操作數(shù)lhs和rhs通過<=>比較可能產(chǎn)生3種結果,該結果可以和0比較,小于0、等于0或者大于0分別對應lhs < rhs、lhs == rhs和lhs > rhs。舉例來說:

#include<iostream>

int main(int argc,char* argv[]){
    bool b = 7<=>11 <0;
    std::cout<<std::boolalpha<<b<<std::endl;
    b = 7<=>11 ==0;
    std::cout<<std::boolalpha<<b<<std::endl;
    b = 7<=>11 >0;
    std::cout<<std::boolalpha<<b<<std::endl;
    b = 7<=>7 ==0;
    std::cout<<std::boolalpha<<b<<std::endl;
    return 0;
}

輸出:

true
false
false
true

請注意,運算符<=>的返回值只能與0和自身類型來比較,如果同其他數(shù)值比較,編譯器會報錯:

#include<iostream>

int main(int argc,char* argv[]){
    bool b = 7<=>11 <100;//編譯失敗,<=>的結果不能與除0以外的數(shù)值比較
    std::cout<<std::boolalpha<<b<<std::endl;
    return 0;
}

二、三向比較的返回類型

<=>的返回結果并不是一個普通類型,根據(jù)標準三向比較會返回3種類型,分別為std::strong_ordering、std::weak_ordering以及std::partial_ordering,而這3種類型又會分為有3~4種最終結果。

2.1 std::strong_ordering

std::strong_ordering類型有3種比較結果,分別為std::strong_ ordering::less、std::strong_ordering::equal以及std::strong_ ordering::greater。表達式lhs <=> rhs分別表示lhs < rhs、lhs == rhs以及l(fā)hs > rhs。std::strong_ordering類型的結果強調(diào)的是strong的含義,表達的是一種可替換性,簡單來說,若lhs == rhs,那么在任何情況下rhs和lhs都可以相互替換,也就是fx(lhs) == fx(rhs)。

對于基本類型中的int類型,三向比較返回的是std::strong_ordering,例如:

用MSVC編譯運行以上代碼,會在輸出窗口顯示class std::strong_ ordering,刻意使用MSVC是因為它的typeid(x).name()可以輸出友好可讀的類型名稱。

對于有復雜結構的類型,std::strong_ordering要求其數(shù)據(jù)成員和基類的三向比較結果都為std::strong_ordering。例如:

#include<iostream>

struct B{
    int a;
    long b;
    auto operator <=> (const B&) const = default;
};

struct D : B{
    short c;
    auto operator <=> (const D&) const = default;
};

int main(int argc,char* argv[]){
    D x1,x2;
    std::cout<<typeid(decltype(x1 <=> x2)).name()<<std::endl;
}

上面這段代碼用MSVC編譯運行會輸出class std::strong_ordering。

請注意,默認情況下自定義類型是不存在三向比較運算符函數(shù)的,需要用戶顯式默認聲明,比如在結構體B和D中聲明auto operator <=> (const B&) const = default;和auto operator <=> (const D&)const = default;。

 如果刪除基類的<=>運算符,派生類顯式定義的<=>將被刪除。

如果刪除派生類的<=>,保留基類的<=>,還可以運行。

 對結構體B而言,由于int和long的比較結果都是std::strong_ordering,因此結構體B的三向比較結果也是std::strong_ordering。同理,對于結構體D,其基類和成員的比較結果是std::strong_ordering,D的三向比較結果同樣是std::strong_ordering。

另外,明確運算符的返回類型,使用std::strong_ ordering替換auto也是沒問題的。

2.2 std::weak_ordering

std::weak_ordering類型也有3種比較結果,分別為std::weak_ ordering::less、std::weak_ordering::equivalent以及std::weak_ ordering::greater。std::weak_ordering的含義正好與std::strong_ ordering相對,表達的是不可替換性。即若有l(wèi)hs == rhs,則rhs和lhs不可以相互替換,也就是fx(lhs) != fx(rhs)。這種情況在基礎類型中并沒有,但是它常常發(fā)生在用戶自定義類中,比如一個大小寫不敏感的字符串類:

#include <compare>
#include <string>
#include <iostream>

int ci_compare(const char* s1, const char* s2)
{
  while (tolower(*s1) == tolower(*s2++)) {
       if (*s1++ == '\0') {
            return 0;
       }
  }
  return tolower(*s1) - tolower(*--s2);
}

class CIString {
public:
  CIString(const char *s) : str_(s) {}

  std::weak_ordering operator<=>(const CIString& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) <=> 0;//strong_ordering返回為weak_ordering類型,實際上發(fā)生了類型轉換
  }
private:
  std::string str_;
};

int main(int argc,char* argv[])
{
    auto res = 'a'<=>'a';
    std::cout << typeid(res).name()<<std::endl;      //strong_ordering
    std::cout << typeid(res<=>0).name()<<std::endl;  //strong_ordering
    std::cout << typeid( ((std::weak_ordering)res) ).name()<<std::endl; //strong_ordering可以轉為weak_ordering
    
    CIString s1{ "HELLO" }, s2{"hello"};
    std::cout << std::boolalpha << (s1 <=> s2 == 0)<<std::endl; // 輸出為true
    std::cout << typeid(s1<=>s2).name()<<std::endl;  //weak_ordering
    return 0;
}

以上代碼實現(xiàn)了一個簡單的大小寫不敏感的字符串類,它對于s1和s2的比較結果是std::weak_ordering::equivalent,表示兩個操作數(shù)是等價的,但是它們不是相等的也不能相互替換。當std::weak_ordering和std::strong_ ordering同時出現(xiàn)在基類和數(shù)據(jù)成員的類型中時,該類型的三向比較結果是std::weak_ordering,例如:

#include <compare>
#include <string>
#include <iostream>

int ci_compare(const char* s1, const char* s2)
{
  while (tolower(*s1) == tolower(*s2++)) {
       if (*s1++ == '\0') {
            return 0;
       }
  }
  return tolower(*s1) - tolower(*--s2);
}

class CIString {
public:
  CIString(const char *s) : str_(s) {}

  std::weak_ordering operator<=>(const CIString& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) <=> 0;//strong_ordering返回為weak_ordering類型,實際上發(fā)生了類型轉換
  }
private:
  std::string str_;
};

struct B{
    int a=0;
    long b=0;
    std::strong_ordering operator <=> (const B&) const = default;
};

struct D : B{
    CIString c{""};
    auto operator <=> (const D&) const = default;
};

int main(int argc,char* argv[])
{
    D w1,w2;
    std::cout << std::boolalpha << (w1 <=> w2 == 0)<<std::endl; // 輸出為true
    std::cout << std::boolalpha << (w1 <=> w2 == std::weak_ordering::equivalent)<<std::endl; // 輸出為true
    std::cout << typeid(w1<=>w2).name()<<std::endl;  //weak_ordering
    return 0;
}

用MSVC編譯運行上面這段代碼會輸出class std::weak_ordering,因為D中的數(shù)據(jù)成員CIString的三向比較結果為std::weak_ordering。請注意,如果顯式聲明默認三向比較運算符函數(shù)為std::strong_ordering operator <=> (const D&) const = default;,那么一定會遭遇到一個編譯錯誤。

2.3 std::partial_ordering

std::partial_ordering類型有4種比較結果,分別為std::partial_ ordering::less、std::partial_ordering::equivalent、std::partial_ ordering::greater以及std::partial_ordering::unordered。std:: partial_ordering約束力比std::weak_ordering更弱,它可以接受當lhs == rhs時rhs和lhs不能相互替換,同時它還能給出第四個結果std::partial_ordering::unordered,表示進行比較的兩個操作數(shù)沒有關系。比如基礎類型中的浮點數(shù):

#include <iostream>

int main(int argc,char* argv[])
{
    std::cout << typeid(decltype(7.7 <=> 11.1)).name();//輸出partial_ordering
    return 0;
}

用MSVC編譯運行以上代碼會輸出class std::partial_ordering。之所以會輸出class std::partial_ordering而不是std::strong_ordering,是因為浮點的集合中存在一個特殊的NaN,它和其他浮點數(shù)值是沒關系的:

#include <iostream>

int main(int argc,char* argv[])
{
    std::cout<<std::boolalpha<< ((0.0/0.0 <=> 1.0) == std::partial_ordering::unordered);//輸出true
    return 0;
}

這段代碼編譯輸出的結果為true。

當std::weak_ordering和std:: partial_ordering同時出現(xiàn)在基類和數(shù)據(jù)成員的類型中時,該類型的三向比較結果是std::partial_ordering,例如:

#include <compare>
#include <string>
#include <iostream>
 
int ci_compare(const char* s1, const char* s2)
{
  while (tolower(*s1) == tolower(*s2++)) {
       if (*s1++ == '\0') {
            return 0;
       }
  }
  return tolower(*s1) - tolower(*--s2);
}
 
class CIString {
public:
  CIString(const char *s) : str_(s) {}
 
  std::weak_ordering operator<=>(const CIString& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) <=> 0;//strong_ordering返回為weak_ordering類型,實際上發(fā)生了類型轉換
  }
private:
  std::string str_;
};
 
struct B{
    int a=0;
    long b=0;
    std::strong_ordering operator <=> (const B&) const = default;
};
 
struct D : B{
    CIString c{""};
    float u=0.0;
    auto operator <=> (const D&) const = default;
};
 
int main(int argc,char* argv[])
{
    D w1,w2;
    std::cout << std::boolalpha << (w1 <=> w2 == 0)<<std::endl; // 輸出為true
    std::cout << std::boolalpha << (w1 <=> w2 == std::partial_ordering::equivalent)<<std::endl; // 輸出為true
    std::cout << typeid(w1<=>w2).name()<<std::endl;  //partial_ordering
    return 0;
}

用MSVC編譯運行以上代碼會輸出class std::partial_ordering,因為D中的數(shù)據(jù)成員u的三向比較結果為std::partial_ordering,同樣,顯式聲明為其他返回類型也會讓編譯器報錯。在C++20的標準庫中有一個模板元函數(shù)std::common_comparison_category,它可以幫助我們在一個類型合集中判斷出最終三向比較的結果類型,當類型合集中存在不支持三向比較的類型時,該模板元函數(shù)返回void。

再次強調(diào)一下,std::strong_ordering、std::weak_ordering和`std::partial_ordering`只能與`0`和類型自身比較。深究其原因,是這3個類只實現(xiàn)了參數(shù)類型為自身類型和`nullptr_t的比較運算符函數(shù)。

三、對基礎類型的支持

  • 3.1.對兩個算術類型的操作數(shù)進行一般算術轉換,然后進行比較。其中整型的比較結果為std::strong_ordering,浮點型的比較結果為std::partial_ordering。例如7 <=> 11.1中,整型7會轉換為浮點類型,然后再進行比較,最終結果為std::partial_ordering類型。
  • 3.2.對于無作用域枚舉類型和整型操作數(shù),枚舉類型會轉換為整型再進行比較,無作用域枚舉類型無法與浮點類型比較:
enum color {
  red
};

auto r = red <=> 11;   //編譯成功
auto r = red <=> 11.1; //編譯失敗
  • 3.3.對兩個相同枚舉類型的操作數(shù)比較結果,如果枚舉類型不同,則無法編譯。
  • 3.4.對于其中一個操作數(shù)為bool類型的情況,另一個操作數(shù)必須也是bool類型,否則無法編譯。比較結果為std::strong_ordering。
  • 3.5.不支持作比較的兩個操作數(shù)為數(shù)組的情況,會導致編譯出錯,例如:
int arr1[5];
int arr2[5];
auto r = arr1 <=> arr2; // 編譯失敗
  • 3.6.對于其中一個操作數(shù)為指針類型的情況,需要另一個操作數(shù)是同樣類型的指針,或者是可以轉換為相同類型的指針,比如數(shù)組到指針的轉換、派生類指針到基類指針的轉換等,最終比較結果為std::strong_ordering:
char arr1[5];
char arr2[5];
char* ptr = arr2;
auto r = ptr <=> arr1;

上面的代碼可以編譯成功,若將代碼中的arr1改寫為int arr1[5],則無法編譯,因為int [5]無法轉換為char *。如果將char * ptr = arr2;修改為void * ptr = arr2;,代碼就可以編譯成功了。

四、自動生成的比較運算符函數(shù)

4.1 std::rel_ops的作用

標準庫中提供了一個名為std::rel_ops的命名空間,在用戶自定義類型已經(jīng)提供了==運算符函數(shù)和<運算符函數(shù)的情況下,幫助用戶實現(xiàn)其他4種運算符函數(shù),包括!=、>、<=和>=。

 代碼:

#include <compare>
#include <string>
#include <iostream>
#include <utility>
 
int ci_compare(const char* s1, const char* s2)
{
  while (tolower(*s1) == tolower(*s2++)) {
       if (*s1++ == '\0') {
            return 0;
       }
  }
  return tolower(*s1) - tolower(*--s2);
}
 
class CIString2 {
public:
  CIString2(const char* s) : str_(s) {}

  bool operator < (const CIString2& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) < 0;
  }
  
  bool operator== (const CIString2& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) == 0;
  }
private:
  std::string str_;
};


int main(int argc,char* argv[])
{
    using namespace std::rel_ops;
    CIString2 s1( "hello" ), s2( "world" );
    bool r = true;
    r = s1 == s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 != s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 > s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 >= s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 < s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 <= s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    return 0;
}

輸出:

false
true
false
false
true
true

4.2 使用<=>

不過因為C++20標準有了三向比較運算符的關系,所以不推薦上面這種做法了。C++20標準規(guī)定,如果用戶為自定義類型聲明了三向比較運算符,那么編譯器會為其自動生成<、>、<=和>=這4種運算符函數(shù)。對于CIString我們可以直接使用這4種運算符函數(shù):

#include <compare>
#include <string>
#include <iostream>
#include <utility>
 
int ci_compare(const char* s1, const char* s2)
{
  while (tolower(*s1) == tolower(*s2++)) {
       if (*s1++ == '\0') {
            return 0;
       }
  }
  return tolower(*s1) - tolower(*--s2);
}
 
class CIString {
public:
  CIString(const char *s) : str_(s) {}
  
//   bool operator== (const CIString& b) const {
//       return ci_compare(str_.c_str(), b.str_.c_str()) == 0;
//   }
 
  std::weak_ordering operator<=>(const CIString& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) <=> 0;//strong_ordering返回為weak_ordering類型,實際上發(fā)生了類型轉換
  }
private:
  std::string str_;
};

int main(int argc,char* argv[])
{
    CIString s1( "hello" ), s2( "world" );
    bool r = true;
    // r = s1 == s2;
    // std::cout<<std::boolalpha<<r<<std::endl;
    // r = s1 != s2;
    // std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 > s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 >= s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 < s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 <= s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    return 0;
}

輸出

false
false
true
true

那么這里就會產(chǎn)生一個疑問,很明顯三向比較運算符能表達兩個操作數(shù)是相等或者等價的含義,為什么標準只允許自動生成4種運算符函數(shù),卻不能自動生成==和=!這兩個運算符函數(shù)呢?實際上這里存在一個嚴重的性能問題。在C++20標準擬定三向比較的早期,是允許通過三向比較自動生成6個比較運算符函數(shù)的,而三向比較的結果類型也不是3種而是5種,多出來的兩種分別是std::strong_ equality和std::weak_equality。但是在提案文檔p1190中提出了一個嚴重的性能問題。簡單來說,假設有一個結構體:

struct S {
    std::vector<std::string> names;
    auto operator<=>(const S &) const = default;
};

它的三向比較運算符的默認實現(xiàn)這樣的:

template<typename T>
std::strong_ordering operator<=>(const std::vector<T>& lhs, const std::vector<T> & rhs) 
{
    size_t min_size = min(lhs.size(), rhs.size());
    for (size_t i = 0; i != min_size; ++i) {
        if (auto const cmp = std::compare_3way(lhs[i], rhs[i]); cmp != 0) {
            return cmp;
        }
    }
    return lhs.size() <=> rhs.size();
}

這個實現(xiàn)對于<和>這樣的運算符函數(shù)沒有問題,因為需要比較容器中的每個元素。但是==運算符就顯得十分低效,對于==運算符高效的做法是先比較容器中的元素數(shù)量是否相等,如果元素數(shù)量不同,則直接返回false:

template<typename T>
bool operator==(const std::vector<T>& lhs, const std::vector<T>& rhs)
{
    const size_t size = lhs.size();
    if (size != rhs.size()) {
        return false;
    }

    for (size_t i = 0; i != size; ++i) {
        if (lhs[i] != rhs[i]) {
            return false;
        }
    }
    return true;
}

想象一下,如果標準允許用三向比較的算法自動生成==運算符函數(shù)會發(fā)生什么事情,很多舊代碼升級編譯環(huán)境后會發(fā)現(xiàn)運行效率下降了,尤其是在容器中元素數(shù)量眾多且每個元素數(shù)據(jù)量龐大的情況下。很少有程序員會注意到三向比較算法的細節(jié),導致這個性能問題難以排查?;谶@種考慮,C++委員會修改了原來的三向比較提案,規(guī)定聲明三向比較運算符函數(shù)只能夠自動生成4種比較運算符函數(shù)。由于不需要負責判斷是否相等,因此std::strong_equality和std::weak_ equality也退出了歷史舞臺。對于==和!=兩種比較運算符函數(shù),只需要多聲明一個==運算符函數(shù),!=運算符函數(shù)會根據(jù)前者自動生成:

#include <compare>
#include <string>
#include <iostream>
#include <utility>
 
int ci_compare(const char* s1, const char* s2)
{
  while (tolower(*s1) == tolower(*s2++)) {
       if (*s1++ == '\0') {
            return 0;
       }
  }
  return tolower(*s1) - tolower(*--s2);
}
 
class CIString {
public:
  CIString(const char *s) : str_(s) {}
  
  bool operator== (const CIString& b) const {
      return ci_compare(str_.c_str(), b.str_.c_str()) == 0;
  }
 
  std::weak_ordering operator<=>(const CIString& b) const {
       return ci_compare(str_.c_str(), b.str_.c_str()) <=> 0;//strong_ordering返回為weak_ordering類型,實際上發(fā)生了類型轉換
  }
private:
  std::string str_;
};

int main(int argc,char* argv[])
{
    CIString s1( "hello" ), s2( "world" );
    bool r = true;
    r = s1 == s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 != s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 > s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 >= s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 < s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    r = s1 <= s2;
    std::cout<<std::boolalpha<<r<<std::endl;
    return 0;
}

false
true
false
false
true
true

五、兼容他舊代碼

現(xiàn)在C++20標準已經(jīng)推薦使用<=>和==運算符自動生成其他比較運算符函數(shù),而使用<、==以及std::rel_ops生成其他比較運算符函數(shù)則會因為std::rel_ops已經(jīng)不被推薦使用而被編譯器警告。那么對于老代碼,我們是否需要去實現(xiàn)一套<=>和==運算符函數(shù)呢?其實大可不必,C++委員會在裁決這項修改的時候已經(jīng)考慮到老代碼的維護成本,所以做了兼容性處理,即在用戶自定義類型中,實現(xiàn)了<、==運算符函數(shù)的數(shù)據(jù)成員類型,在該類型的三向比較中將自動生成合適的比較代碼。比如:

#include <iostream>
 
struct Legacy {
  int n=0;
  bool operator==(const Legacy& rhs) const
  {
       return n == rhs.n;
  }
  bool operator<(const Legacy& rhs) const
  {
       return n < rhs.n;
  }
};

struct TreeWay {
  Legacy m;
  std::strong_ordering operator<=>(const TreeWay &) const = default;
};

int main(int argc,char* argv[])
{
    TreeWay t1, t2;
    bool r = t1 < t2;
    std::cout<<std::boolalpha<<r<<std::endl;
    return 0;
}

在上面的代碼中,結構體TreeWay的三向比較操作會調(diào)用結構體Legacy中的<和==運算符來完成,其代碼類似于:

struct TreeWay {
  Legacy m;
  std::strong_ordering operator<=>(const TreeWay& rhs) const {
       if (m < rhs.m) return std::strong_ordering::less;
       if (m == rhs.m) return std::strong_ordering::equal;
       return std::strong_ordering::greater;
  }
};

需要注意的是,這里operator<=>必須顯式聲明返回類型為std::strong_ ordering,使用auto是無法通過編譯的。

到此這篇關于c++20引入的三路比較操作符<=>的文章就介紹到這了,更多相關c++20三路比較操作符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++通過文件指針獲取文件大小的方法實現(xiàn)

    C++通過文件指針獲取文件大小的方法實現(xiàn)

    本文主要介紹了C++通過文件指針獲取文件大小的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++深入探究不同的繼承體系

    C++深入探究不同的繼承體系

    繼承是C++面向對象編程中的一門。繼承是子類繼承父類的特征和行為,或者是繼承父類得方法,使的子類具有父類得的特性和行為。重寫是子類對父類的允許訪問的方法實行的過程進行重新編寫,返回值和形參都不能改變。就是對原本的父類進行重新編寫,但是外部接口不能被重寫
    2022-05-05
  • 詳解C語言中rand函數(shù)的使用

    詳解C語言中rand函數(shù)的使用

    在編程時我們有時總希望自己產(chǎn)生一個隨機數(shù)字,以供使用,那么下面介紹rand函數(shù)的使用,有需要的可以參考學習。
    2016-08-08
  • C語言MFC基礎之計算器詳解

    C語言MFC基礎之計算器詳解

    這篇文章主要為大家介紹了MFC實現(xiàn)簡單的計算器,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-08-08
  • OpenCV實現(xiàn)鼠標在圖像上框選單目標和多目標

    OpenCV實現(xiàn)鼠標在圖像上框選單目標和多目標

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)鼠標在圖像上框選單目標和多目標,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 使用C語言編寫圣誕表白程序

    使用C語言編寫圣誕表白程序

    圣誕節(jié)快到了,讓我們用C語言制作一個圣誕表白程序吧,下面通過本文學習下實現(xiàn)代碼
    2016-12-12
  • 用C語言如何打印一個等腰三角形

    用C語言如何打印一個等腰三角形

    這篇文章主要介紹了用C語言如何打印一個等腰三角形,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語言中atoi函數(shù)模擬實現(xiàn)詳析

    C語言中atoi函數(shù)模擬實現(xiàn)詳析

    atoi函數(shù)功能是將數(shù)字字符串轉換為整數(shù),比如數(shù)字字符串"12345"被atoi轉換為12345,數(shù)字字符串"-12345"被轉換為-12345,下面這篇文章主要給大家介紹了關于C語言中atoi函數(shù)模擬實現(xiàn)的相關資料,需要的朋友可以參考下
    2022-10-10
  • 帶你了解C++的IO流

    帶你了解C++的IO流

    這篇文章主要介紹了C++ IO流的相關資料,幫助大家更好的理解和學習c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2021-09-09
  • C++類中如何使用定義的類型別名

    C++類中如何使用定義的類型別名

    這篇文章主要介紹了C++類中如何使用定義的類型別名,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評論