成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++的未來(lái)和指針

開(kāi)發(fā) 后端
上周Meeting C++2013結(jié)束后,我對(duì)C++思考了很多,有一些內(nèi)容和指針有關(guān)。在C++ 11中只對(duì)指針進(jìn)行了小量的更新(引入了nullptr),不過(guò)過(guò)去幾年中,C++中指針的語(yǔ)義和用法卻發(fā)生了很多變化。

上周Meeting C++2013結(jié)束后,我對(duì)C++思考了很多,有一些內(nèi)容和指針有關(guān)。在C++ 11中只對(duì)指針進(jìn)行了小量的更新(引入了nullptr),不過(guò)過(guò)去幾年中,C++中指針的語(yǔ)義和用法卻發(fā)生了很多變化。

首先,我們從指針的原始意義開(kāi)始,C++11中簡(jiǎn)單如type* pt = nullptr; 這里的指針是C語(yǔ)言中的核心概念,由于C++沒(méi)有重新設(shè)計(jì)指針,據(jù)我所知C也沒(méi)用更新這部分語(yǔ)義。但是C規(guī)范中定義了指針,并給出了在C和C++中使用指 針的指導(dǎo)。事實(shí)上,指針是一個(gè)指向內(nèi)存中存儲(chǔ)某個(gè)變量的地址。如果你對(duì)指針進(jìn)行解引用操作,就能訪問(wèn)指針指向的變量。指針實(shí)際上是一個(gè)基礎(chǔ)變量,它不知道 它所指向的值是否有效,也不能感知其指向的值是否無(wú)效。在C語(yǔ)言中,一個(gè)指針指向0,說(shuō)明其不指向任何值,因此也不具有有個(gè)有效的值。所有其他指針都應(yīng)該 指向內(nèi)存中有意義的地址。但實(shí)際上,有些指針沒(méi)有正確的初始化,或者干脆越出了應(yīng)有的范圍。

在C++11中,將指針正確初始化為0的方法是使用關(guān)鍵字nullptr。這讓計(jì)算機(jī)知道該指針當(dāng)前為空。另外,還有一種常用的方式是將0定義為 NULL或者其他定義或聲明。C++11中使用nullptr統(tǒng)一了這種方式。C++中還引入了引用,它看起來(lái)像是變量的別名,其優(yōu)勢(shì)是使用引用的時(shí)候必 須先初始化,因此,在引用生命周期起始時(shí)需要指向一個(gè)有效地址。不過(guò),引用也只是指針的解引用,所以,一旦其引用的變量作用范圍結(jié)束,其引用也無(wú)效了,使 用指針時(shí),你可以將指針置為0,但是針對(duì)引用卻不能這么做。

但是在C++11和在C++11標(biāo)準(zhǔn)之前,一些事情發(fā)生了變化,指針是語(yǔ)言的核心概念,但是你在現(xiàn)代化的C++代碼和函數(shù)庫(kù)中卻很少看到它們。遠(yuǎn)在 C++11之前,boost創(chuàng)建了一系列非常有用的智能指針類,針對(duì)指針進(jìn)行了封裝,對(duì)其核心機(jī)制通過(guò)操作符重載。智能指針本身不是一個(gè)指針,而是一個(gè)棧 上的變量或?qū)ο蟪蓡T。智能指針使用了RAII來(lái)解決指針的一些問(wèn)題,這并不是指針的職責(zé)。當(dāng)在椎中分配內(nèi)存時(shí),new返回了指向該部分內(nèi)存的地址,所以每 分配一塊動(dòng)態(tài)內(nèi)存,就需要使用一個(gè)指針,相當(dāng)于創(chuàng)建對(duì)象的一個(gè)操作句柄。但是指針僅僅是一個(gè)簡(jiǎn)單的變量,不知道變量的擁有關(guān)系,也不能自動(dòng)釋放堆上的內(nèi)存 空間。智能指針擔(dān)當(dāng)了這一角色,擁有指針并在變量超出作用域時(shí)自動(dòng)管理其堆上的值。在棧上的值意味著,一旦相應(yīng)的棧被銷毀,其管理的堆上的值會(huì)被自動(dòng)釋 放,即使是在發(fā)生異常的情況下。

過(guò)去的一些年,C++出現(xiàn)了一些不同風(fēng)格的使用,從使用類的C及大量使用指針,到類似我想Widget和QT這樣面向?qū)ο蟮目蚣堋T谶^(guò)去5-10年 中的形成的一種新樣式被認(rèn)為是現(xiàn)代C++,一種趨向盡力發(fā)掘語(yǔ)言本身擴(kuò)展能力,并試圖找到不同特性針對(duì)不同場(chǎng)合的應(yīng)用。值得注意的是boost在這一趨勢(shì) 中起到了***風(fēng)范的C++框架。C++標(biāo)準(zhǔn)在設(shè)計(jì)其標(biāo)準(zhǔn)庫(kù)時(shí)也借鑒了這一點(diǎn)。與此同時(shí),值語(yǔ)義變得流行起來(lái),并且與move語(yǔ)義成為未來(lái)C++一個(gè)關(guān)鍵點(diǎn)。來(lái)自Tony van Eerds在Meeting C++的一份備忘幻燈片引起了我對(duì)指針的思考。它有兩列,一個(gè)代表引用語(yǔ)義,一個(gè)代表值語(yǔ)義,以及其朗朗上口的主題詞:

哦,不!使用指針 vs 哦,不要使用指針!

所以,在C++11或者后續(xù)的C++14,使用值語(yǔ)義的趨勢(shì)蓋過(guò)了使用指針。指針在取后臺(tái)還是工作著,不過(guò)在新的C++14中,new和 delete都將不能直接使用,new被抽象化為make_shared/make_unique。其內(nèi)部使用了new,但是返回一個(gè)智能指針。 shared_ptr 和 unique_ptr都表現(xiàn)為值語(yǔ)義類型。智能指針同樣在其作用域結(jié)束時(shí)使用delete釋放內(nèi)存。這讓我思考,C++中的指針是不是都可以填充不同的 “角色”,或者被替換掉。

繼承和虛擬函數(shù)

指針一個(gè)非常重要的用途是在繼承中使用指針來(lái)指向一系列擁有相同接口的類型值。我想用Shape例子來(lái)闡明這一點(diǎn),這里有一個(gè)基類Shape,同時(shí) 其含有一個(gè)虛擬函數(shù)叫area的方法。同時(shí),它還有幾個(gè)派生類叫Rectange,Cirecle和Triangle。現(xiàn)在,有一個(gè)指針容器(比 如:std::vector<Shape*>)來(lái)容納指向不同形狀的對(duì)象指針,每個(gè)對(duì)象都有自己的計(jì)算面積方法。這是C++中最常用指針的方 式,尤其是在面向?qū)ο髸r(shí)。現(xiàn)在,好消息是,這里同樣支持使用智能指針,當(dāng)其使用這些智能指針時(shí),內(nèi)部會(huì)進(jìn)行訪問(wèn)指針。Boost中甚至還有一個(gè)指針容器, 能在清空容器時(shí)自動(dòng)釋放其中的智能指針元素。

現(xiàn)在考慮虛函數(shù)調(diào)用(這雖然不和指針有直接聯(lián)系),虛函數(shù)調(diào)用通常會(huì)有點(diǎn)點(diǎn)慢,同時(shí)也不容易編譯器針對(duì)其進(jìn)行優(yōu)化。所以,如果其類型在運(yùn)行時(shí)是可知 的,就可以使用靜態(tài)分發(fā)或者編譯器多態(tài)性來(lái)正確調(diào)用相應(yīng)的虛函數(shù)方法,而不是在運(yùn)行時(shí)使用虛函數(shù)指針。作為一種模式被叫做CRTP,已經(jīng)實(shí)現(xiàn)了這一方式。 最近的研究顯示,這在gcc4.8中可以提高性能。有趣的是,通常情況下使用gcc4.9,優(yōu)化器可以針對(duì)動(dòng)態(tài)分發(fā)進(jìn)行更進(jìn)一步的優(yōu)化。還是讓我們繼續(xù)回到指針。

不確定指針

有時(shí)候指針被用于有一系列可選值作為參數(shù)或者返回不確定的函數(shù)中,通常都默認(rèn)為0,用戶可以選擇傳遞一個(gè)有效的指針給該函數(shù)。或者在返回的情況下, 函數(shù)返回一個(gè)空指針表示執(zhí)行失敗,這在C++中也是一個(gè)有效的使用方式。同樣的,這里可以使用智能指針,智能指針可以扮演指針的操作句柄。不過(guò)常常會(huì)導(dǎo)致 過(guò)量使用(使用堆),或者并沒(méi)有替代不確定的角色。這需要使用一個(gè)可選值類型來(lái)代替,用于確定其存儲(chǔ)的值是否有效。Boost庫(kù)有一個(gè)boost::optional來(lái)表示可選值類型。因此,可以考慮在C++14中引入有一個(gè)類似的可選類型。所以,現(xiàn)在std::optional會(huì)被移入到技術(shù)預(yù)覽版(TS)中,將來(lái)會(huì)變成C++14或者C++1y的一部分。

當(dāng)前的標(biāo)準(zhǔn)庫(kù)中已經(jīng)使用了一些可選類型,比如std::set::insert會(huì)返回一個(gè)pair<iterator,bool>類 型,其第二個(gè)參數(shù)表示請(qǐng)求值是否插入到set容器中。容器通常返回尾迭代器來(lái)表示無(wú)效,但是如果要求返還一個(gè)值時(shí),這個(gè)角色過(guò)去通常都是用指針來(lái)表示,指 針為0表示函數(shù)執(zhí)行失敗,因此這里的指針可以被可選類型替代:

  1. optional<MyValue> ov = queryValue(42); 
  2. if(ov) 
  3.   cout << *ov; 
  4. else 
  5.   cerr << "value could not be retrieved"

因此,可選類型和智能指針類型替代了指針的一部分語(yǔ)義,填充了其角色。但是它們是值語(yǔ)義,并大部分都在棧上使用。

有效的指針

在寫(xiě)作我對(duì)C++指針用法的思考時(shí),我主要關(guān)注于那些指針可以被其他(比如:智能指針和可選類型等)替換的場(chǎng)景,但是低估了實(shí)際上有些場(chǎng)景指針仍然有用。感謝來(lái)自reddit,email和社交媒體的一些反饋。

非擁有者指針就是這樣一個(gè)例子,這里未來(lái)的幾年還是需要使用指針。shard_ptr有對(duì)應(yīng)的weak_ptr,但是unique_ptr沒(méi)有對(duì)應(yīng)的伙伴。這里就需要使用非擁有者原始指針。比如,在一個(gè)由父和子對(duì)象構(gòu)成的樹(shù)或者圖中。但是,未來(lái)C++中會(huì)新增exempt_ptr來(lái)代替。

在處理函數(shù)中的傳遞的值時(shí),指針還是具有用處的,Herb Sutter寫(xiě)了一篇非常好的文章:《GotW about this in May》。Eric Niebler 在他的Meeting C++會(huì)議的筆記中也談及了,同時(shí)移動(dòng)語(yǔ)義會(huì)影響你應(yīng)該如何在函數(shù)中傳遞或者返回值。

Category

C++11

Input Arguments

 

small/POD/sink

pass by value

all others

pass by const ref

Output

return by value

Input/Output

non const ref / stateful Algorithm Object

這個(gè)表格來(lái)自 Eric Nieblers 的筆記, 請(qǐng)看幻燈片中的16/31 (建議你閱讀所有的幻燈片)

Eric Niebler說(shuō)過(guò),在能使用移動(dòng)語(yǔ)義時(shí)盡可能使用移動(dòng)語(yǔ)義。一個(gè)可選參數(shù)為例,vector::emplace_back接收一個(gè)參數(shù),當(dāng)其只是將把元 素移動(dòng)到適當(dāng)位置,這時(shí)你應(yīng)得使用移動(dòng)語(yǔ)義。一些輸出參數(shù)返回一個(gè)值,編譯器可以使用移動(dòng)語(yǔ)義或者CopyEllision(拷貝去除)的優(yōu)化技術(shù)。針對(duì) 一些以對(duì)象為輸入/輸出參數(shù),非常引用也是可選擇性優(yōu)化的,但是Eric在他的筆記中指出:對(duì)象算法的狀態(tài)在構(gòu)造函數(shù)中應(yīng)使用槽參數(shù)。

在傳遞常量(非常量)引用時(shí),指針可以做同樣的事情,不過(guò)有些不同,你需要對(duì)指針測(cè)試其是否為空。我個(gè)人更喜歡在函數(shù)/方法或者構(gòu)造函數(shù)時(shí)傳遞引用而不是指針。

指針計(jì)算

之前我提到過(guò),從我個(gè)人的觀點(diǎn),指針只是一個(gè)普通的變量,其值指向一個(gè)地址,或者更精確地說(shuō),是其指向值得一個(gè)地址號(hào)碼。這個(gè)地址號(hào)碼可以被復(fù)制, 你可以對(duì)其進(jìn)行加或減法操作。這常常用于遍歷數(shù)組或者計(jì)算兩個(gè)指針的的距離,這在使用數(shù)組時(shí)很有用。這里對(duì)數(shù)組的便利其實(shí)就是迭代器,所以,在實(shí)際代碼 時(shí),指針可以代替迭代器使用。但是,從我多年C++開(kāi)發(fā)經(jīng)驗(yàn)來(lái)看,我?guī)缀鯖](méi)有用到針對(duì)指針的計(jì)算操作。而且在C++中,指針的計(jì)算已經(jīng)有了非常好的抽象。 我的觀點(diǎn)是,理解指針計(jì)算是重要的,這有助于理解代碼中指針的具體作用。

再見(jiàn),指針?

理論上,C++可以不使用指針,但是由于指針是C/C++語(yǔ)言的核心概念,指針本身仍然會(huì)繼續(xù)存在。但是它的角色會(huì)變更,在你使用C++時(shí),你不再 需要考慮指針。隨著C++的繼續(xù)發(fā)展,C++11和C++14朝著更抽象,對(duì)開(kāi)發(fā)者更友好的方向發(fā)展。使用智能指針和可選類型,指針要么被封裝從而更適用 安全的值類型,要么完全被它們替代掉。

原文鏈接:http://www.meetingcpp.com/index.php/br/items/cpp-future-and-the-pointer.html

譯文鏈接:http://blog.jobbole.com/56312/

責(zé)任編輯:陳四芳 來(lái)源: 伯樂(lè)在線
相關(guān)推薦

2024-05-15 16:01:04

C++編程開(kāi)發(fā)

2009-09-16 14:56:23

C++

2021-06-10 08:51:57

C++指針聲明指針相關(guān)概念

2011-04-11 11:09:50

this指針

2021-12-21 15:31:10

C++語(yǔ)言指針

2023-11-22 13:22:51

C++函數(shù)

2010-01-18 15:53:27

C++析構(gòu)函數(shù)

2011-07-13 16:14:53

C++引用指針

2010-01-26 13:42:28

C++指針

2011-04-19 16:38:00

對(duì)象指針指針C++

2011-07-15 01:38:56

C++this指針

2011-04-19 09:19:09

C++指針

2024-07-03 12:04:42

C++this?

2021-10-27 16:27:20

C++指針操控

2010-01-28 13:57:19

C++指針基礎(chǔ)

2011-07-20 16:43:34

C++

2024-04-10 12:14:36

C++指針算術(shù)運(yùn)算

2024-01-09 09:23:12

指針C++

2011-04-11 14:18:37

CC++指針

2024-01-25 11:42:00

C++編程指針常量
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产精品久久久久久久岛一牛影视 | 999久久久久久久久6666 | aa级毛片毛片免费观看久 | 日本免费一区二区三区 | 久精品久久 | 国产乱肥老妇国产一区二 | 国产精品久久久久无码av | 欧美片网站免费 | 久久国产精品久久久久久久久久 | 91精品国产高清一区二区三区 | 久国产视频 | 色橹橹欧美在线观看视频高清 | 国产精品一区二区三区久久 | 国产精品久久精品 | 99re在线| 久久久久久久久久久福利观看 | 成人欧美日韩一区二区三区 | 一区二区中文字幕 | 亚洲人成网亚洲欧洲无码 | 国产一区二区三区精品久久久 | 在线亚洲免费 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 国产精品不卡一区 | 国产日韩免费视频 | 91私密视频 | 日日噜| pacopacomama在线| 欧美一级黄视频 | 亚洲二区在线 | 免费av电影网站 | 中国av在线免费观看 | 国产精品日日摸夜夜添夜夜av | 欧美久久久久久久 | 国产7777 | 久久久女女女女999久久 | 天堂资源最新在线 | 国产在线一区观看 | 中文字幕高清免费日韩视频在线 | 午夜在线 | www.99热 | 天堂国产 |