1樓:yc znone
C語言沒有物件,沒有引用,也就不存在移動語義了。C語言只有資料和指標。
C++的移動語義指的是所有權和資料從源物件轉移到目的物件,源物件復位。移動語義基於RAII、複製和右值引用擴充套件來的,用在兩個方面:
1.可以複製但複製成本高的物件,可以使用移動操作避免複製成本。
2.不可以複製但可以移動的物件。如果沒有移動語義就要分別建立實體物件和控制代碼物件,實體物件管理資料,不可以複製;控制代碼物件(類似std::
ref)必須引用實體物件,但可以複製。實際使用時有時不如移動方便。
2樓:Sinon
move語義是c++抽象層次上去之後又要做到zero-overhead必須的東西.
move涉及的抽象層次主要涉及這兩個:
函式過載, 讓介面統一
return by value, 讓指標少一點.
效能的話c怎麼可能比c++差嘛, c++想做的就是寫起來爽, with zero overhead, 接近c的水平就可以了.
3樓:邱昊宇
「移動」的提法簡直是個大坑,人們浪費了大把時間在理解並說服自己相信這個比喻上。
也許把「移動」說成是「某種會半自動擦屁股的淺拷貝」比較好理解。C++ 只是在語言層面提供了右值引用、各種自動巢狀呼叫保證、特殊語法之類的支援(就像構造、析構之於 C 語言那一套 OOP 的改進一樣)。
這樣問題就變成了「C 語言可以安全地做淺拷貝嗎?」,結論就顯而易見了。
以下為空白處的塗鴉:
#include
#include
#include
struct
widget
;// 構造
// Widget::Widget(size_t)
struct
widget
*widget_create
(size_t
size
)// 隨便啥操作舉個例子
// Widget::describe(char const *)
void
widget_describe
(struct
widget*w
,char
const
*tag
)// 析構
// Widget::~Widget()
void
widget_destroy
(struct
widget*w
)// 預設複製構造(滑稽)
// Widget::Widget(Widget const&) = default
struct
widget
*widget_copy_wtf
(struct
widget
*src
)// 複製構造
// Widget::Widget(Widget const&)
struct
widget
*widget_copy
(struct
widget
*src
)// 預設移動構造(滑稽)
// Widget::Widget(Widget&&) = default
struct
widget
*widget_move_wtf
(struct
widget
*src
)// 移動構造
// Widget::Widget(Widget&&)
struct
widget
*widget_move
(struct
widget
*src
)int
main
()關於「值語義」「引用語義」「移動語義」我覺得不應該將概念侷限在 C++ 的語法上。因為 C++ 提供的構造、成員函式、操作符過載的語法,讓我們把 X 語義和物件本身進行了繫結,但這只是 C++ 的語法特性,這些特定恰巧讓物件的性質、使用方法看上去符合某些特徵,不應該要求所有語言中都以此特徵為定義。
無論是 C 標準庫中的 FILE 還是上面例子裡的 struct widget 物件本身,相關操作都需要通過 fXX 或者 widget_XX 函式實現。例如 widget_copy 實現值語義的複製操作、widget_move 實現移動語義的移動操作、還可以以此類推出 widget_assign(a, b) 實現值語義的賦值操作……不能因為它們不是 C++ 中的複製建構函式、移動建構函式、賦值操作符過載形式,寫起來也不是 a = Widget(b)、a = Widget(move(b))、a = b,而否定它們對應操作的語義。
同時,每種語言也有各自的慣用寫法,例如使用 ADT 封裝例子裡的 struct widget,通過 struct widget * 來引用真實的 struct widget 物件。不能因為 struct widget * 本身是指標,而說 struct widget 物件是引用語義,這是兩種不同的物件,只不過 ADT 的習慣是不直接拿物件,而是用指標指。
4樓:暮無井見鈴
(1) 我不太清楚移動語義是否內置於語言。 C++ 的移動語義主要是在語核外實現的,語核提供的是辨明移動語義的型別(右值引用)。
理論上移動構造和移動賦值也能翻譯成 C ,這算不算給 C 賦予了移動語義呢?
(2) 個人認為正確實現的話效率沒有區別。
(3) 問題大概是兩方面:
1) 我們希望表示獨佔的資源柄型別能從函式裡返回,並且標記為不可複製。
( 以前的 auto_ptr 相當難用,有 unique_ptr 後就銷聲匿跡了)
2) 對於存在深複製的型別,我們希望有時能讓新物件奪取舊物件的內容,以避免深複製。適合的場合有從函式返回、交換、在陣列結構中移動等。
沒有(或不需要用)移動語義的語言使用自動的 GC ,直接淺複製即可。背後的物件在變為不可達後才被釋放。
題外話:
沒有語核支援的古代 C++ 裡也能實現移動語義:給每個需要深複製的類 Value 寫個 ValueMover 類(有個 mutable Value 成員),兩者可相互從彼此構造或賦值(後者建構函式/賦值運算子的引用引數要去掉 const 以允許奪取)。
只是這種做法會破壞 RVO/NRVO 優化,而且輔助類容易用錯卻必須暴露出來,也沒有標準庫支援。
5樓:
1,沒有,沒有
2,不會,因為c沒有copy 構造
3,move 解決了copy構造中臨時構造的右值浪費問題,沒有move語義的語言,一般都是傳引用,再配合gc,不需要move。
6樓:機犬
move 是給拷貝建構函式擦屁股的,拷貝建構函式最廣泛的用處是實現值語義的引用型別,於是需要移動建構函式來避免不必要的記憶體分配,你不寫移動建構函式 move 不會做任何事,C 連屁股都沒有要擦什麼。
C 11 的move語義,從語言功能正交性來看,是一種必須的語義嗎?
圓形畢露 Move語意不是必須的,它的作用是為了提高程式效率。Move語意和右值有關,在C 11中,編譯器能夠根據函式引數是左值還是右值決定呼叫copy constructor還是move constructor。右值從狹義上說就是沒有identity的表示式,比如匿名物件,通過隱式轉換的物件.這些...
C 11中的move語義減少了臨時物件和物件複製嗎?
槓吐血評論員陶某 move應該是針對你的物件中有在堆上分配記憶體這種情況而設定的,你舉的例子恰好不符合這種情況。看下面這個例子 classA A A A other A operator A other return this int p int main A中有堆上分配的變數p時,呼叫move語義...
自學C語言和C ,有什麼好書推薦嗎
呵呵 有c語言基礎的話推薦 essential C 然後推薦 C primer 再就是 effective c 和 more effective C 最後就是 STL原始碼剖析 之類的。 小北師兄 C 語言入門書籍 c primer plus,這本書內容全面,是入門的一本好書,我當時自學 C語言的時...