C++11用例

 

Initiallizer list、auto type 、foreach 、nullptr 代替了c++ 03的NULL、enum class代替了c++03的enum,更安全、override关键标识 for virtual function (更加安全,直观 )、final关键标识 ,主要是class 及virtual function、关键字default标识, compiler generated default constructor、关键标识 delete ,放在函数后面,表示函数不能被调用、lambda function, 让编程更优雅、tuple元祖

 

1、Initiallizer list

       //c++03
	std::vector<int> v;
	v.push_back(2);
	v.push_back(3);

	//c++ 11
	std::vector<int> v{ 1,2,3 };

2、auto type 

std::vector<int> vec = { 1,2,3,4 };
	//c++ 03
	for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
		std::cout << *it << std::endl;
	}

	//c++ 11
	for (auto it = vec.begin(); it != vec.end(); it++) {
		std::cout << *it << std::endl;
	}

	auto a = 3 + 2;
	auto s = "123";

3. foreach 写c++像是再写c#

std::vector<int> vec = { 1,2,3,4 };
	//c++ 03
	for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
		std::cout << *it << std::endl;
	}

	//c++ 11
	//read only(只读)
	for (auto i : vec) {
		std::cout << i << std::endl;
	}
        //只读
        for (const auto& i : vec) {
		std::cout << i << std::endl;
	}
	//changes the values in v(修改)
	for (auto& i : vec) {
		i = 3;
	}

4. nullptr 代替了c++ 03的NULL

5. enum class代替了c++03的enum,更安全

        //c++ 03
	enum ship {
		bulkship,
		tankership
	};

	//c++ 11
	enum class ship1 {
		bulkship,
		tankership
	};

6. override关键标识 for virtual function (更加安全,直观 )

class base {
public:
	virtual void fun1(int);
	virtual void fun2() const;
	void fun3(int);
};

class son :public base {
	//c++ 03 存在隐患
	/*
	void fun1(float);  //不小心写错了参数,ok 编译通过,create a new func
	void fun2();       //不小心少写了const,ok 编译通过,create a new func
	void fun3();
	*/

	// but in c++ 11 更安全清晰
	void fun1(float) override; //编译Error: no func to override
	void fun2() override;      //编译Error: no func to override
	void fun3() override;      //编译Error: no func to override			
};

7. final关键标识 ,主要是class 及virtual function

//this is means no class can be derived from CPoint2D
class CPoint2D final {
	//No class can override Draw
	virtual void Draw() final;
};

8. 关键字default标识, compiler generated default constructor

强制编译器生成默认构造函数

  • 编译器不再生成默认构造函数
class CPoint2D {
public:
	CPoint2D(double x_,double y_) {
		x = x_;
		y = y_;
	}
	double x;
	double y;
};

int main(){	
	CPoint2D pt;//编译报错,不存在默认构造函数,因为编译器不再生成	
}
  • 通过default force compiler to generate the default constructor
class CPoint2D {
public:
	CPoint2D(double x_,double y_) {
		x = x_;
		y = y_;
	}
	CPoint2D() = default;//告诉编译器强制生成
	double x;
	double y;
};

int main(){	
	CPoint2D pt;//ok	
}

9. 关键标识 delete ,放在函数后面,表示函数不能被调用

  • 看以前的情形,构造函数只接受int,但是输入double也是可以的,因为会自动转换
class dog {
public:
	dog(int age_) {
		age = age_;
	}
	int age;
};

int main(){	
	dog(2);   //ok
	dog(4.5); //also ok,converted form double to int
}
  • c++ 11 解决方案
class dog {
public:
	dog(int age_) {
		age = age_;
	}
	dog(double) = delete;
	int age;
};

int main(){	
	dog(2);   //ok
	dog(4.5); //not ok,已经删除的函数
}

10. lambda function, 让编程更优雅

像c#一样优雅起来

int main(){	
	std::cout << [](int x, int y) {return x + y; }(3, 5) << std::endl;
}

我经常使用std::sort对结构体配合Lammda匿名函数使用,比如点的数组按照x升序排列

class CPoint2D {
public:
	CPoint2D(double x1,double y1) {
		x = x1; y = y1;
	}
	double x;
	double y;
};
int main(){

	std::vector<CPoint2D> Pts{ {1,1},{3,3},{2,2} };
	std::sort(begin(Pts), end(Pts), [](const CPoint2D& pt1, const CPoint2D& pt2) {
		return  pt1.x < pt2.x;
		});
}

11.smart pointer 智能指针

12. tuple元祖

  • std::pair<std::string,int>的扩展版,可以当做一个通用的结构体来使用
  • tuple某些情况下会让代码的易读性变差
  • 什么情况下使用tuple

std::pair<>的扩展版,可多个参数

	std::pair<int, std::string> p = std::make_pair(2, "hello");
	//std::pair的扩展版
	std::tuple<int, std::string, char> t(2,"foo",'a');
	auto t1 = std::make_tuple(0, "dog", 'b');
	std::cout << std::get<0>(t) << std::endl;
	std::cout << std::get<1>(t) << std::endl;
	std::cout << std::get<2>(t) << std::endl;

易读性会变差(一个使用结构体,一个使用tuple)

结构体比较清晰 p1.name p1.age

tuple易读性差,通过 std::get<0>(t2) std::get<1>(t2)取值

你会想what stored in position 0&what stored in position 1?

	struct person {
		std::string name;
		int age;
	};
	person p1;
	std::tuple<std::string, int> t2;

	//把上面的代码遮挡起来 tuple会导致代码的易读性降低
	std::cout << p1.name << p1.age<<std::endl;
	std::cout << std::get<0>(t2) << std::get<1>(t2) << std::endl;
	//what stored in position 0?  what stored in position 1?

when to use tuple

(1) As a one-time only structure to transfer g group of data 比如作为函数的返回值使用,这样就不用声明结构体了

std::tuple<std::string,int> GetNameAge(){
	return std::make_tuple("lcl", 20);
}

(2)comparison of tuples

//hours, minutes, seconds

	//comparison of tuples
	std::tuple<int, int, int> time1, time2;  
	if (time1 > time2) {
		//...
	}

(3)Muti index map

std::map<std::tuple<int, char, double>, float> m;
上一篇:Python中tuple和list有什么区别?Python入门!


下一篇:Scala常规操作之数组、List、Tuple、Set、Map