日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

262-C++ C11标准

發布時間:2023/12/20 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 262-C++ C11标准 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.C++中的類型轉換分為四種形式:

C語言中的轉換都是沒有意義的,就是說C語言中的強轉都是(int) (int*)這樣的類型,你不知道它這么轉的意義是什么,意義不夠明確,所以C++中給出了4種類型轉換

①static_cast:值的轉換,相當于C語言中的強轉,這個轉換意義很明確就是將float類型轉成整型

int a = 10; float ft = 12.23; a = static_cast<int>(ft);//轉成int ft = static_cast<float>(a);//轉成float

②const_cast:是去常性強轉,C語言的這種方式int* p = (int*)&a;的意義并不明確,而C++中的int* p = const_cast<int*>(&a);意義非常明確,就是去常性

const int a = 10; int* p = (int*)&a;//C語言方式 int* p = const_cast<int*>(&a);//C++方式

③reinterpret_cast:是對指針進行重新解釋的轉換

int a = 10; int* p = &a; char* cp = (char*)&a;//C語言方式 char* cp = reinterpret_cast<char*>(&a);

④dynamic_cast:動態強制類型轉換:將子對象的地址強轉成父指針

Object* op = NULL; Base* bp = NULL;Object obj; Base base;op = &base;//C方式ok bp = &Object;//C方式,error op = dynamic_cast<Object*>(&base);//C++,ok bp = dynamic_cast<Object*>(&base);//error

就是說C++使類型轉換的意義更明確了

2.std::move移動構造函數的內部是怎樣實現

my_remove_reference可以移除引用特質,也就是說無論傳進來的是int類型,還是int&類型,還是int&&類型,type永遠都是int類型

template<class _Ty> struct my_remove_reference {using type = _Ty;using Const_thru_ref_type = const _Ty; };template<class _Ty> struct my_remove_reference<_Ty&> {using type = _Ty;using Const_thru_ref_type = const _Ty&; };template<class _Ty> struct my_remove_reference<_Ty&&> {using type = _Ty;using Const_thru_ref_type = const _Ty&&; };template<class _Ty> using my_remove_reference_t = typename my_remove_reference<_Ty>::type;template<class _Ty> my_remove_reference_t<_Ty>&& my_move(_Ty&& _Arg) {return static_cast<my_remove_reference_t<_Ty>&&>(_Arg); }int main(){my_remove_reference<int>::type;//type是int類型my_remove_reference<int&>::type;//type是int類型my_remove_reference<int&&>::type;//type是int類型return 0; }

也就是說std::move不管傳進來的是int類型,還是int&類型,還是int&&類型,都會通過重命名using type = _Ty;使type一直保持是int類型,然后通過static_cast轉成右值去調用移動構造函數

template<class _Ty> struct my_remove_reference {my_remove_reference() { cout << "_Ty" << endl; }using type = _Ty;using Const_thru_ref_type = const _Ty; };template<class _Ty> struct my_remove_reference<_Ty&> {my_remove_reference() { cout << "_Ty&" << endl; }using type = _Ty;using Const_thru_ref_type = const _Ty&; };template<class _Ty> struct my_remove_reference<_Ty&&> {my_remove_reference() { cout << "_Ty&&" << endl; }using type = _Ty;using Const_thru_ref_type = const _Ty&&; };template<class _Ty> using my_remove_reference_t = typename my_remove_reference<_Ty>::type;template<class _Ty> my_remove_reference_t<_Ty>&& my_move(_Ty&& _Arg) {return static_cast<my_remove_reference_t<_Ty>&&>(_Arg); }int main(){string s0("sun");string s1("hello");//左值string s2("nihao");//左值const string& s3 = s0;//常性左值引用string& s4 = s1;//左值引用string&& s5 = string("nihaohello");//s4左值string s6(my_move(s2));string s7(my_move(s3));//s7和s3都是sun,因為是const,會調用拷貝構造函數string s8(my_move(s4));//s4空,s8hellostring s9(my_move(s5));//s5空,s8nihaohelloreturn 0; }

注意:它并不能去掉常性,所以這種方式是很安全的,對于s3來說,他是個常引用,把它的資源交給s7是不允許的,所以會調用拷貝構造函數,給s7賦值,所以s3和s7的值是一樣的,同樣對于移動賦值來說也是一樣的

只有int &&r = 10;這種是右值引用,const int&& x = 100;是一個左值常性引用

對于下面模板來說,_Ty&& a屬于型別未定義(就是說還不確定a是一個什么類型),他可以接收左值、右值、引用都可以

template<class _Ty> void fun(_Ty&& a) {}

3.會實例化出兩個版本,一個是Base<0>,一個是Base<1>


4.在模板類中,引用的疊加問題,所有情況下a都是一個左值

template<class _Ty> void fun(_Ty&& a) {} int main() {int a = 10;//左值int& b = a;//左值int&& c = 10;//左值fun(a);fun(b);fun(c);fun(20);//20是右值return 0; }

在C11標準之前,函數的重載依靠的是形參列表的不同來進行重載的,在C11標準以后,引入了左值、右值、將亡值的概念,如果這個變量可以取地址,就是一個左值,如果這個變量不能取地址,就是一個右值,如果這個變量是在表達式中或者在函數的返回中,就是一個將亡值,一般將亡值可以處理成右值,但是將亡值一旦具有名了,就是一個左值了

所以C++可以根據是否是左值還是右值進行重載

void fun(int&); void fun(const int&); void fun(int&&);

可以看到所有情況下a都是左值,Add函數的返回值作為參數傳遞進去以后,也被當成了左值來處理

當使用完美轉發時,20是一個右值,傳給a后,依然保持著右值的屬性,Add函數返回值是一個將亡值,完美轉發情況下,保持其右值的屬性不變

所以完美轉發的作用就是使在程序的運行過程中,使變量的屬性不變

左值和右值疊加是左值
左值和左值疊加是左值
右值和左值疊加是左值
右值和右值疊加是右值

5.auto的初始化類型的方式

auto是一個占位符,當auto在推導的時候,auto x = 10;在編譯的時候就會推導出auto是一個int類型,然后用int類型替換掉auto

const int e = 10; auto f = e;推導出f的類型是int類型,auto& f1 = e;推導出f1是一個const int類型,因為f1是e的引用,不能而e是一個const類型,所以f1也必須是const類型

只有是靜態常性整型量static const auto num = 0;時,可以直接初始化,其他情況不能直接初始化

注意:auto不能作為函數的參數

6.C11標準中,在定義類型的時候,可以預給值,并不是真的給值,當調用默認構造函數的時候,會用預值進行初始化

是在構建對象時,調用默認構造函數的時候,用預值進行的初始化

當實現了構造函數時,就不能調用默認構造函數了

如果構造函數有默認值,就必須都傳遞參數

如果構造函數沒有參數默認值,這樣就都可以編譯通過

auto不能用于推導 集合當中

auto可以推演出函數的返回類型,這兩種方式都是可以的,但是前提是你自己心里要清楚begin的返回值是一個什么樣的迭代器類型,這樣使用auto就可以簡寫,很方便


auto并沒有性能的提升,只是編寫代碼更方便了,但是對于瀏覽源碼來說也帶來了一定的難度,對于開發者來說,別人不容易讀懂我的代碼了,可以帶來效益

7.decltype是一個操作符,可以根據表達式推演出類型

decltype也可以推導出函數的返回值類型,一般情況下都用不到decltype

8.nullptr和NULL的區別

系統在定義NULL的時候,如果是C++,就把NULL定義成了0,否則就把0強轉成無類型((void*)0)

對于編譯器來說,無論是0還是無類型0都具有二義性,都把他當作一個整型來看待,C11為了解決這個問題,引入了一個關鍵字nullptr,它是一個關鍵字,認為它是一個空指針常量,nullptr可以給一切指針類型賦值,所以在編寫程序時,盡可能的使用nullptr

9.C11標準中初始化方式

10.Object a();編譯器會認為這是一個聲明,Object();是類型加括號,會調用構造函數

總結

以上是生活随笔為你收集整理的262-C++ C11标准的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。