国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】C++11 -- 新功能

這篇具有很好參考價值的文章主要介紹了【C++】C++11 -- 新功能。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

C++11 – 新功能

默認(rèn)成員函數(shù)

在C++11之前一個類有6個默認(rèn)成員函數(shù),在C++11標(biāo)準(zhǔn)中又新增了兩個默認(rèn)成員函數(shù),分別是移動構(gòu)造函數(shù)和移動賦值函數(shù)

默認(rèn)移動構(gòu)造和移動賦值生成的條件

  • 移動構(gòu)造函數(shù)的生成條件:沒有自己實現(xiàn)移動構(gòu)造函數(shù),并且沒有自己實現(xiàn)析構(gòu)函數(shù),拷貝構(gòu)造函數(shù)和拷貝賦值函數(shù)
  • 移動賦值重載函數(shù)的生成條件:沒有自己實現(xiàn)移動賦值重載函數(shù),并且沒有自己實現(xiàn)析構(gòu)函數(shù),拷貝構(gòu)造函數(shù),拷貝賦值函數(shù)

也就是說移動構(gòu)造和移動賦值的生成條件和之前六個默認(rèn)成員函數(shù)不同,并不是不寫就會生成默認(rèn)的。

特別注意,如果我們自己實現(xiàn)了移動構(gòu)造和移動賦值,就算沒有實現(xiàn)拷貝構(gòu)造和拷貝賦值,先一起也不會生成默認(rèn)的拷貝構(gòu)造和拷貝賦值

默認(rèn)移動構(gòu)造函數(shù)會做什么

  • 默認(rèn)生成的移動構(gòu)造函數(shù):對于內(nèi)置類型的成員可以完成值拷貝(淺拷貝),對于自定義類型的成員,如果該成員實現(xiàn)了移動構(gòu)造就調(diào)用它的移動構(gòu)造,否則就調(diào)用它的拷貝構(gòu)造
  • 默認(rèn)生成生成的移動賦值函數(shù):對于內(nèi)置類型的成員會完成值拷貝(淺拷貝),對于自定義類型成員,如果該成員實現(xiàn)了移動賦值就調(diào)用它的移動賦值,否則就調(diào)用它的拷貝賦值

驗證默認(rèn)生成的移動構(gòu)造函數(shù)和移動賦值函數(shù)所做的工作

要驗證默認(rèn)生成的移動構(gòu)造和移動賦值所做的工作,這里使用了類一個簡化版的string類,其中只編寫了幾個我們需要的成員函數(shù)

//
// Created by 陳李鑫 on 2023/7/16.
//
#ifndef SIMULATION_REALIZATION_STL_CLX_STRING_HPP
#define SIMULATION_REALIZATION_STL_CLX_STRING_HPP

#endif //SIMULATION_REALIZATION_STL_CLX_STRING_HPP

#include <iostream>
#include <algorithm>
#include <utility>
#include <cassert>


class clx_string{
public:
    typedef char* iterator;
    iterator begin() { return _str;}
    iterator end() { return _str + _size; }
    const char* c_str() const { return const_cast<const char*>(_str); };
    void swap(clx_string& s);
    clx_string(const char* str = "");
    clx_string(const clx_string& s);
    clx_string(clx_string&& s);
    ~clx_string();
    clx_string& operator=(const clx_string& s);
    clx_string& operator=(clx_string&& s);
    char& operator[](size_t i);
    void reserve(size_t n);
    void push_back(char ch);
    clx_string& operator+=(char ch);
    static clx_string to_string(int value);
private:
    char* _str;
    size_t _size;
    size_t _capacity;
};

void clx_string::swap(clx_string& s) {
    std::swap(_size, s._size);
    std::swap(_capacity, s._capacity);
    std::swap(_str, s._str);
}

clx_string::clx_string(const char* str) {
    std::cout << "clx_string(const char* str) -- 直接構(gòu)造" << std::endl;
    _size = strlen(str);
    _capacity = _size;
    _str = new char[_capacity + 1];
    strcpy(_str, str);
}

clx_string::clx_string(clx_string&& s)
    :_size(0), _capacity(0), _str(nullptr)
{
    std::cout << "clx_string::clx_string(clx_string&& s) -- 移動構(gòu)造" << std::endl;
    swap(s);
}

// 拷貝構(gòu)造函數(shù) 以前的寫法
//clx_string::clx_string(const clx_string& s) {
//    _size = strlen(s.c_str());
//    _capacity = _size;
//    _str = new char[_capacity + 1];
//    strcpy(_str, s.c_str());
//}

// 拷貝構(gòu)造函數(shù) 現(xiàn)代寫法
clx_string::clx_string(const clx_string& s)
    : _str(nullptr), _size(0), _capacity(0)
{
    std::cout << "clx_string(const clx_string& s) -- 拷貝構(gòu)造"  << std::endl;
    clx_string tmp(s.c_str());
    swap(tmp);
    std::cout << std::endl;
    std::cout << std::endl;
}

clx_string::~clx_string() {
    _size = 0;
    _capacity = 0;
    delete[] _str;
    _str = nullptr;
}
clx_string& clx_string:: operator=(const clx_string& s) {
    std::cout << "clx_string& clx_string:: operator=(const clx_string& s) -- 賦值函數(shù)重載" << std::endl;
    clx_string tmp(s.c_str());
    clx_string::swap(tmp);
    std::cout << std::endl;
    std::cout << std::endl;
    return *this;
}

clx_string& clx_string::operator=(clx_string&& s) {
    std::cout << "clx_string& clx_string::operator=(clx_string&& s) -- 移動賦值重載" << std::endl;
    swap(s);
    return *this;
}



char& clx_string::operator[](size_t i) {
    assert(0 <= i && i < _size);
    return _str[i];
}

void clx_string::reserve(size_t n) {
    if (n > _capacity) {
        char* tmp = new char[n + 1];
        strncpy(tmp, _str, _size + 1);
        if (_str) {
            delete[] _str;
        }
        _str = tmp;
        _capacity = n;
    }
}
void clx_string::push_back(char ch) {
    while (_size >= _capacity) {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
    }
    _str[_size] = ch;
    _str[_size + 1] = 0;
    _size++;
}
clx_string& clx_string::operator+=(char ch) {
    push_back(ch);
    return *this;
}

clx_string clx_string::to_string(int value) {
    clx_string res;
    bool flag = false;
    if (value < 0) {
        flag = true;
        value = -1 * value;
    }
    while (value > 0) {
        char ch = static_cast<char>(value % 10);
        res += ch + '0';
        value /= 10;
    }
    if(flag) res += '-';
    std::reverse(res.begin(), res.end());
    return res;
}

然后再編譯一個簡單的Person類,Person類中的成員name的類型就是我們模擬實現(xiàn)的string類

class Person{
public:
    explicit Person(const char* name = "", int age = 0)
        :_name(name), _age(age)
    {}
    Person(const Person& p) 
        :_name(p._name)
        ,_age(p._age)
    {}
    
    Person& operator=(const Person& p) {
        if (this != &p) {
            _name = p._name;
            _age = p._age;
        }
        return *this;
    }
    
private:
    clx_string _name;   // 姓名
    int _age;           // 年齡
};

雖然Person類當(dāng)中沒有實現(xiàn)移動構(gòu)造和移動賦值,但是拷貝構(gòu)造,拷貝賦值,析構(gòu)函數(shù)都實現(xiàn)了,因此Person類不會生成默認(rèn)的移動構(gòu)造和移動賦值

void clx_person_test1() {
    Person s1("clx", 21);
    Person s2 = std::move(s1);
}
// 輸出
clx_string(const char* str) -- 直接構(gòu)造
clx_string(const clx_string& s) -- 拷貝構(gòu)造
clx_string(const char* str) -- 直接構(gòu)造

可以看到我們已經(jīng)使用右值取構(gòu)造s2但是Person類并沒有調(diào)用默認(rèn)生成的移動構(gòu)造函數(shù),因為_name作為自定義類型并沒有調(diào)用其的移動構(gòu)造以及移動賦值。這里調(diào)用的是Person的拷貝構(gòu)造函數(shù),其又調(diào)用了clx_string類的拷貝構(gòu)造函數(shù)

生成默認(rèn)移動構(gòu)造和移動賦值

為了讓Person調(diào)用默認(rèn)生成的移動構(gòu)造函數(shù)和移動賦值函數(shù),我們需要將Person類的拷貝構(gòu)造,拷貝賦值,析構(gòu)函數(shù)都注釋掉,再次運行上述代碼

clx_string(const char* str) -- 直接構(gòu)造
clx_string::clx_string(clx_string&& s) -- 移動構(gòu)造

可以看到Person類默認(rèn)生成了移動構(gòu)造函數(shù),其對自己的自定義成員_name調(diào)用了自定義成員的移動構(gòu)造函數(shù)_,我們還可以改一下代碼看一下默認(rèn)移動賦值的效果

void clx_person_test1() {
    Person s1("clx", 21);
    Person s2;
    s2 = s1;
}
clx_string(const char* str) -- 直接構(gòu)造
clx_string(const char* str) -- 直接構(gòu)造
clx_string& clx_string:: operator=(const clx_string& s) -- 賦值函數(shù)重載
clx_string(const char* str) -- 直接構(gòu)造

類成員變量初始化

默認(rèn)生成的構(gòu)造函數(shù),對于其自定義類型的成員會調(diào)用其構(gòu)造函數(shù)進行初始化,但并不會對內(nèi)置類型的成員進行處理。于是對于C++11支持非靜態(tài)成員變量在聲明時初始化賦值,默認(rèn)生成的構(gòu)造函數(shù)會使用這些缺省值對成員進行初始化

struct student{
    string s = "clx";
    int age = 18;
};

void clx_student_test1() {
    student s;
    cout << s.s << endl;			// clx
    cout << s.age << endl;    // 18
}

注意這里只是聲明,是給聲明的成員變量一個缺省值。不是定義!不是定義!

強制生成默認(rèn)函數(shù)關(guān)鍵字default

C++11可以讓我們更好的控制要使用的默認(rèn)成員函數(shù),假設(shè)某些情況我們需要使用某個默認(rèn)成員函數(shù),但是因為某些原因?qū)е聼o法生成這個默認(rèn)成員函數(shù),就可以使用default這個關(guān)鍵字強制其生成

struct student{
    student(const student& stu)
        : s(stu.s), age(stu.age){}
        
    string s = "clx";
    int age = 18;
};
void clx_student_test2() {
    student s;
}

這樣就不行,編譯就會報錯。因為Person類中編寫了拷貝構(gòu)造函數(shù),導(dǎo)致無法生成默認(rèn)的構(gòu)造函數(shù)。默認(rèn)的構(gòu)造函數(shù)生成條件是沒有編寫任何類型的構(gòu)造函數(shù),包括拷貝構(gòu)造函數(shù)

struct student{
    student() = default;          // 默認(rèn)生成構(gòu)造函數(shù)
    student(const student& stu)
        : s(stu.s), age(stu.age){}

    string s = "clx";
    int age = 18;
};

這樣我們可以使用default關(guān)鍵字強制生成默認(rèn)構(gòu)造函數(shù)。

default不僅能生成默認(rèn)構(gòu)造,所有默認(rèn)成員函數(shù)都可以用default關(guān)鍵字強制生成,包括移動構(gòu)造和移動賦值.

class Person{
public:
    explicit Person(const char* name = "", int age = 0)
        :_name(name), _age(age)
    {}
    Person(const Person& p)
        :_name(p._name)
        ,_age(p._age)
    {}

    Person& operator=(const Person& p) {
        if (this != &p) {
            _name = p._name;
            _age = p._age;
        }
        return *this;
    }
    ~Person(){}
    Person(Person&&) = default;								// 生成默認(rèn)的移動賦值和拷貝函數(shù)
    Person& operator=(Person&&) = default;
private:
    clx_string _name;   // 姓名
    int _age;           // 年齡
};

void clx_person_test1() {
    Person s1("clx", 21);
    Person s2 = move(s1);
}
clx_string(const char* str) -- 直接構(gòu)造
clx_string::clx_string(clx_string&& s) -- 移動構(gòu)造

可以看到默認(rèn)的移動賦值函數(shù)是生成了的

禁用生成默認(rèn)函數(shù)的關(guān)鍵字delete

如果我們想要限制某些默認(rèn)函數(shù)生成時,可以通過一下幾種方式

  • C++98: 將函數(shù)設(shè)置成私有,并只聲明不實現(xiàn),這樣外部調(diào)用該函數(shù)就會報錯
  • C++11:在該函數(shù)的聲明后面加上=delete,表示不讓編譯器生成該函數(shù)的默認(rèn)版本

final and override 關(guān)鍵字

final 修飾的類

final修飾的類被稱為最終類,最終類無法被繼承

class UnInheritable final {}

Final 修飾虛函數(shù)

final修飾的虛函數(shù),表示該虛函數(shù)不能再被重寫,如果字類繼承后重寫了該虛函數(shù)編譯就會報錯

Override 修飾虛函數(shù)

override修飾的字類虛函數(shù),檢查該類是否是由父類繼承下來的并且必須重寫,如果沒有重寫就會報錯文章來源地址http://www.zghlxwxcb.cn/news/detail-582632.html

到了這里,關(guān)于【C++】C++11 -- 新功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Copilot的11個新功能,你不能錯過!

    Copilot的11個新功能,你不能錯過!

    我的新書 《Android App開發(fā)入門與實戰(zhàn)》 已于2020年8月由人民郵電出版社出版,歡迎購買。點擊進入詳情 微軟發(fā)布了Copilot,這個東西真是太瘋狂了。 如果你不使用它,你就會在2023年落后了。 將Word文檔轉(zhuǎn)換為演示文稿。 從文件中快速創(chuàng)建演示文稿。 通過關(guān)鍵幻燈片總結(jié)冗長

    2024年02月04日
    瀏覽(52)
  • Java 20 新功能介紹

    Java 20 共帶來 7 個新特性功能 ,其中三個是孵化提案,孵化也就是說尚在征求意見階段,未來可能會刪除此功能。 JEP 描述 分類 429 作用域值(孵化器) Project Loom,Java 開發(fā)相關(guān) 432 Record 模式匹配(第二次預(yù)覽) Project Amber,新的語言特性 433 switch 的模式匹配(第四次預(yù)覽)

    2024年02月03日
    瀏覽(25)
  • 官宣Windows11十月的Moment 1來了,新功能!附官方ISO鏡像(簡/繁/英)

    官宣Windows11十月的Moment 1來了,新功能!附官方ISO鏡像(簡/繁/英)

    一個月前(2022年9月)微軟正式發(fā)布了Windows 11的年度大更新——22H2版本(Build 22621.382),過了沒幾天當(dāng)月又推出了Build 22621.525的ISO鏡像。給人一種特別操之過急的感覺~ 前天微軟又向MVS訂閱用戶推送了10月份的累積更新的ISO鏡像,系統(tǒng)版本號Build 22621.674。Windows11也是維持著每

    2024年02月06日
    瀏覽(23)
  • python一點通:數(shù)據(jù)處理頂流Pandas 2.0有什么新功能?

    Pandas 2.0及其后續(xù)版本的發(fā)布引入了各種功能和增強,標(biāo)志著在使用Pandas進行數(shù)據(jù)操作和分析方面的顯著演進。這里是對一些新功能的深入解析: 可選依賴的安裝: 在Pandas 2.0中,通過pip安裝pandas時,可以通過指定extras來安裝一組可選的依賴項,例如:pip install “pandas[performan

    2024年02月08日
    瀏覽(17)
  • 數(shù)據(jù)可視化工具LightningChart .NET正式發(fā)布v10.5.1——擁有全新的3D新功能

    數(shù)據(jù)可視化工具LightningChart .NET正式發(fā)布v10.5.1——擁有全新的3D新功能

    LightningChart.NET完全由GPU加速,并且性能經(jīng)過優(yōu)化,可用于實時顯示海量數(shù)據(jù)-超過10億個數(shù)據(jù)點。 LightningChart包括廣泛的2D,高級3D,Polar,Smith,3D餅/甜甜圈,地理地圖和GIS圖表以及適用于科學(xué),工程,醫(yī)學(xué),航空,貿(mào)易,能源和其他領(lǐng)域的體繪制功能。 LightningChart .NET v10.5.1正

    2024年02月13日
    瀏覽(26)
  • Midjourney新功能:角色參照指南

    基本概念 角色參照(Character Reference) :這個功能允許用戶在不同的圖像生成中保持給定參照角色的一致性。 適用模型 :適用于Midjourney V6和Niji6型號。 功能亮點 跨風(fēng)格一致性 :可以在不同風(fēng)格(如動漫風(fēng)、寫實風(fēng))中保持角色特征一致。 面部、著裝、發(fā)型調(diào)控 :用戶可以

    2024年04月10日
    瀏覽(42)
  • TypeScript 5.1發(fā)布,新功能更新

    TypeScript 5.1發(fā)布,新功能更新

    1:返回類型增加undefined 這里設(shè)置了一個別名 fun,當(dāng)時使用它的時候,我們必須顯示返回一個 undefined 。 現(xiàn)在你可以直接設(shè)置返回類型: 而不僅限于 void any 。 4.3版本 :? 5.1版本 :? 2:getter可以設(shè)置和 setter 的不相關(guān)類型 在之前版本 ,get 返回類型應(yīng)該為 set 的子類型,如

    2024年02月09日
    瀏覽(24)
  • 三星泄露微軟 Copilot 新功能:用自然語言操控各種功能

    三星泄露微軟 Copilot 新功能:用自然語言操控各種功能

    3 月 11 日消息,微軟計劃本月晚些時候發(fā)布新款 Surface 電腦和適用于?Windows 11?的 Copilot 新功能,但三星似乎等不及了,在其即將推出的 Galaxy Book4 系列產(chǎn)品宣傳材料中泄露了一些即將到來的 Copilot 功能。 三星官網(wǎng)上發(fā)布的圖片證實了此前關(guān)于微軟正為其人工智能助手 Copilo

    2024年04月09日
    瀏覽(29)
  • SOLIDWORKS 2023新功能揭秘(一):3D CAD功能的十大更新

    SolidWorks 3D CAD ?軟件擁有設(shè)計、模擬、成本估算、可制造性檢查、CAM、可持續(xù)設(shè)計和數(shù)據(jù)管理等功能,同時還包含適用于鈑金,焊件,曲面,模具,產(chǎn)品配置,DFM和CAM的專業(yè)工具,支持ECAD/MCAD協(xié)作,復(fù)雜的零部件庫以及高級真實感渲染。更重要的是具有結(jié)構(gòu)和運動分析功能,

    2024年02月05日
    瀏覽(18)
  • Microsoft Releases .NET 7新功能

    Microsoft Releases .NET 7新功能

    Microsoft Visual Studio是一種統(tǒng)一的開發(fā)體驗,使開發(fā)人員能夠跨web、云和設(shè)備創(chuàng)建多層應(yīng)用程序。11月8日,微軟發(fā)布了該強大開發(fā)環(huán)境的下一版本:Visual Studio 2022 17.4版。 除了修復(fù)許多頂級報告的bug之外,17.4版還包括了許多基于開發(fā)者社區(qū)建議的新功能,包括: Visual Studio的本

    2024年02月06日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包