// demo3.1.2.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <windows.h> void f(int); void f(void*); void f(std::nullptr_t); //std::nullptr是一個基本類型,可以轉化為空指針,不會轉化為整數 void show(){} int _tmain(int argc, _TCHAR* argv[]) { f(0); //調用f(int) f(NULL); //調用f(int) 本來是想調用f(void*) f(nullptr); //調用f(void*) f(show); //當函數名被用作數值時,會自動轉化為函數指針 f(&show); //這四個全部調用f(std::nullptr_t) f(*show); f(***show); system("pause"); return 0; } void f(int i) { printf("1111111111\n"); } void f(void* p) { printf("22222222222\n"); } void f(std::nullptr_t p) { printf("333333333\n"); }
b.以auto完成類型自動推導
// demo3.2.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <windows.h> double f(){ return 100.0; } int _tmain(int argc, _TCHAR* argv[]) { auto x; //錯誤,auto會根據變量的初值推導類型,所以一定要有初始化操作 auto i = 100; //正確 auto j = f(); //正確 system("pause"); return 0; }
c.一致性初始化與初始列 1.一致性初始化:面對任何初始化動作,都可以使用大括號來初始化。 1 2 int i{ 2 }; std::vector<int> v{ 1, 2, 3, 4, 5, 6 }; 2.初始列:會強迫造成value initialization,即使某個局部變量屬於某個基礎類型,也會被初始化為0或者nullptr。
// demo3.3.2.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <windows.h> #include <vector> void show(std::initializer_list<int> vals) //用戶自定義類型之初始列 { for (auto p = vals.begin(); p != vals.end(); p++) printf("%d ",*p); printf("\n"); } class P { public: P(){}; P(int a, int b){ printf("1111111111111\n"); } explicit P(std::initializer_list<int> va){ printf("2222222222222\n"); } }; int _tmain(int argc, _TCHAR* argv[]) { // int i; //i沒有初始化 int i{}; //i = 0; // int * p; //p沒有初始化 int* p{}; //p初始化為nullptr int j{2}; //窄化(降低精度或數值變動,對於大括號是不成立的) // int k{ 2.1 }; //錯誤 show({12,23,45,6,7,8,1}); P w(1,2); //調用P(int,int),初始列的優先級高 P q{2,1}; //調用P(std::initializer_list<int>) P r{1,1,1}; //調用P(std::initializer_list<int>) //構造函數前面加了explicit,表明只能顯式調用,不能隱式轉化 // P s = {1,1}; //調用P(std::initializer_list<int>) system("pause"); return 0; }
d.范圍for語句
for (auto &i : { 12, 1, 1 }) printf("%d ",i); printf("\n");
e.Move語義和RValue Reference
// demo3.5.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <windows.h> #include <vector> #include <iostream> using namespace std; class People { public: People() //默認構造函數 { x = 0; cout << "1111" << endl; } People(int a) //一個參數的構造函數 { x = a; cout << "2222" << endl; } People(const People& p) //拷貝構造函數 { x = p.x; cout << "3333" << endl; } People(const People&& p) //右值拷貝“構造函數” { cout << "4444" << endl; } People& operator =(const People& p) //重載=運算符 { x = p.x; cout << "5555" << endl; return *this; } int x; };
int _tmain(int argc, _TCHAR* argv[]) { vector<People> v; People p1(100); //2222 People p2; //1111 v.push_back(move(p1)); //move的作用將傳入參數p1轉化為右值,如果有右值拷貝“構造函數”,就搬遷數據 //否則就調用cosnt拷貝構造函數,就拷貝數據,輸出4444 cout << p1.x << endl; //4444,可能是搬運p1的時候,vs2013還保留了p1。 v.push_back(p2); //輸出3333 system("pause"); return 0; }