1. 程式人生 > >C++11新特性總結(列舉+繼承+左右值引用+變長模板)

C++11新特性總結(列舉+繼承+左右值引用+變長模板)

一、列舉+斷言+異常

// C++11的一些新的特性
#include "stdafx.h"
#include <cassert>
using namespace std;
// C++98列舉型別
enum book { c66 = 0x0001, c77 = 0x0002, c88 = 0x0003, c99 = 0x0004 };
// C++11強型別-列舉
enum class bookk { c66 = 0x0001, c77 = 0x0002, c88 = 0x0003, c99 = 0x0004 };
// C++11異常noexcept,如果T會丟擲異常,則fun就可以拋異常
void T() noexcept(false) {}
void fun() noexcept(noexcept(T())) {}
// C++11 final可以防止函式被過載,override過載
int main()
{
	// C++98斷言
	assert((c99 - 1) == (c66 | c77 | c88));
	// C++11靜態斷言,編譯時進行斷言
	static_assert((c99-1) == (c66|c77|c88),"assert_error");
    return 0;
}


二、簡化繼承

// C++11的一些新的特性
#include "stdafx.h"
#include <iostream>
using namespace std;
// 繼承建構函式:通過using,B繼承了A中的所有建構函式
struct A {
	A(int i) {};
	A(double d,int i) {};
	A(float f,int i,const char * c) {};
};
struct B :A {
	using A::A;
	virtual void ExtraInterface() {};
};
// 委派建構函式:
class Info {
public:
	Info():Info(1,'a') { }
	Info(int i) :Info(i, 'a') { }
	Info(char e) :Info(1, e) { }
private:
	Info(int i, char e) :type(i), name(e) {}
	int type;
	char name;
};


int main()
{
    return 0;
}

三、移動語義、左值與右值

// C++11的一些新的特性
#include "stdafx.h"
#include <iostream>
using namespace std;
class myc {
public:
	myc() :d(5) { cout << "我是空構造" << endl; }
	myc(myc && h) :d(h.d) { cout << "我是移動構造" << endl; }
	int d;

};
int main()
{
	// lambda 函式返回右值,原本此右值生命已結束
	auto ReturnRvalue = [=]()->int { return 1 + 2; };
	// 通過右值引用&&,右值又具有了生命
	int && a = ReturnRvalue();
	/*
		如何分辨左值與右值:
			1、可以取地址&的是左值,無法取地址的是右值
			2、將亡值和純右值是右值,有名字的為左值
		注:無法將右值引用繫結給左值,同時,無法將左值引用繫結給右值
	*/
	cout << a << endl;
	myc t;
	t.d = 5;
	// move強制把左值轉化成右值
	myc c(move(t));
	cout << c.d << endl;
    return 0;
}


四、變長模板

// C++11的一些新的特性
#include "stdafx.h"
#include <iostream>
// 引入c語言的引數型別...
#include <cstdarg>
// 引入C++11變長模板
#include <tuple>
using namespace std;
// 定義一個變長引數的函式
double nonconstfunc(int count,...) {
	// 宣告一個引數列表結構變數
	va_list ap;
	double sum = 0;
	// 開始獲取引數,並傳入制定的引數個數
	va_start(ap,count);
	double temp;
	for (int i = 0;i < count;++i)
	{
		temp = va_arg(ap, double);
		cout << temp << endl;
		// 依次取double型的引數
		sum += temp;
	}
	// 結束
	va_end(ap);
	return sum;
}
int main()
{
	// 常量表達式,編譯期間就能確定是常量
	constexpr int i = 1;
	cout << i << endl;
	// 變長函式,隱患是引數型別不一致,就出錯
	printf("%f\n", nonconstfunc(3, 1.1f, 2.0f, 3.3f));
	// C++11引入了變長模板tuple,引數變長,返回值也變長
	auto tp = make_tuple(3,"hello",'W');
	auto tempFunc = [=]()->tuple<int,const char*> {
		cout << get<0>(tp) << get<1>(tp) << get<2>(tp) << endl;
		return make_tuple(get<0>(tp), get<1>(tp));
	};
	auto t = tempFunc();
	cout << get<1>(t) << endl;
    return 0;
}