// 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;
}