C語言有 move 語義嗎?

時間 2021-05-10 01:56:52

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語言的時...