记录几点C++11特性的简单随笔

今天看到一篇关于C++11的一些新的标准特性文章,虽然还没有环境,但是先随手记下。

1. auto关键字

  这个关键字所声明的变量可以被赋值多种类型,应该说近乎所有类型,包括了STL容器的iterator类型等。

  有点类似与Lua和Python的变量,但是不同的是,脚本的变量是不需要手动声明的。

例子:

auto i = 42;        // i is an int 
auto l = 42LL;      // l is an long long 
auto p = new foo(); // p is a foo*
std::map<std::string, std::vector<int>> map;
 for(auto it = begin(map); it != end(map); ++it)  
{
 }

   注意:auto能用于函数返回值声明的情况只存在于,当函数存在返回值类型时。也就是说,必须能够让编译在函数末端判断出返回值类型的情况下。

例子:

template <typename T1, typename T2>
 auto compose(T1 t1, T2 t2) -> decltype(t1 + t2) 
{  
  return t1+t2;
 } 
auto v = compose(2, 3.14); // v's type is double

2.关键字nullptr

   用于取代NULL或者0,以防止前面两者隐式转换成整形。但是nullptr可以转化成bool,前两者也依旧合法。(向厚兼容)

3.for语句的拓展

  可以遍历C类型的数组、初始化列表以及任何重载了非成员的begin()和end()函数的类型。

std::map<std::string, std::vector<int>> map; 
std::vector<int> v;
v.push_back(1); 
v.push_back(2); 
v.push_back(3); 
map["one"] = v;   
for(const auto& kvp : map) 
 {   
    std::cout << kvp.first << std::endl;    
    for(auto v : kvp.second)  
    {
      std::cout << v << std::endl;
    } 
 }  
 int arr[] = {1,2,3,4,5};
 for(int& e : arr) 
 {   
e = e*e;
 } 

4. override 和 final 关键字

    这两个关键字是为了虚函数而存在的。作者在这里举例子说明假如类中进行虚函数重写所遇到的麻烦,个人觉得不是麻烦就不记录了。

     override关键字标记重写虚函数。

     final关键字有点类似与java中用法,最终无法被重载。java中可以修饰class,不知道c++可以不,没有环境无法尝试,表示遗憾啊。。。

例子:

class B
{ public: virtual void f(int) { std::cout << "B::f" << std::endl; } }; class D : public B { public: virtual void f(int) override final {std::cout << "D::f" << std::endl;} }; class F : public D { public: virtual void f(int) override {std::cout << "F::f" << std::endl;} };

 5.Strongly-typed enums强类型枚举

   在枚举声明定义时添加关键字class。枚举常量不会再被暴露到外层作用域中,也不会隐式转化成整形。并且拥有用户指定的特定类型(传统枚举也增加了这个性质)。

例子:

1 enum class Options {None, One, All}; 
2 Options o = Options::All;

接下来的几个不是很了解先记着:

6. SmartPointers智能指针

  • unique_ptr: 如果内存资源的所有权不需要共享,就应当使用这个(它没有拷贝构造函数),但是它可以转让给另一个unique_ptr(存在move构造函数)。
  • shared_ptr:  如果内存资源需要共享,那么使用这个(所以叫这个名字)。
  • weak_ptr: 持有被shared_ptr所管理对象的引用,但是不会改变引用计数值。它被用来打破依赖循环(想象在一个tree结构中,父节点通过一个共享所有权的引用(chared_ptr)引用子节点,同时子节点又必须持有父节点的引用。如果这第二个引用也共享所有权,就会导致一个循环,最终两个节点内存都无法释放)。 
 1 void foo(int* p)
 2 {
 3 std::cout << *p << std::endl;
 4 }
 5 std::unique_ptr<int> p1(new int(42));
 6 std::unique_ptr<int> p2 = std::move(p1); // transfer ownership
 7   
 8 if(p1)
 9 foo(p1.get());
10   
11 (*p2)++;
12   
13 if(p2)
14 foo(p2.get());
void foo(int* p) 
{ 
}
 void bar(std::shared_ptr<int> p) 
{
 ++(*p);
 } 
std::shared_ptr<int> p1(new int(42)); 
std::shared_ptr<int> p2 = p1;  
bar(p1); 
foo(p2.get());
1 auto p3 = std::make_shared<int>(42);

make_shared<T>是一个非成员函数,使用它的好处是可以一次性分配共享对象和智能指针自身的内存。而显示地使用shared_ptr构造函数来构造则至少需要两次内存分配。除了会产生额外的开销,还可能会导致内存泄漏。在下面这个例子中,如果seed()抛出一个错误就会产生内存泄漏。

1 auto p = std::make_shared<int>(42); 
2 std::weak_ptr<int> wp = p; 
3   { 
4 auto sp = wp.lock(); 
5 std::cout << *sp << std::endl; 
6 }  
7  p.reset();  
8  if(wp.expired())
9  std::cout << "expired" << std::endl;

lock()来获得被引用对象的shared_ptr,如果你试图锁定(lock)一个过期(指被弱引用对象已经被释放)的weak_ptr,那你将获得一个空的shared_ptr.

7. 非成员 begin()和end()

 1 template <typename Iterator>
 2 void bar(Iterator begin, Iterator end)
 3 {
 4 std::for_each(begin, end, [](int n) {std::cout << n << std::endl;});
 5   
 6 auto is_odd = [](int n) {return n%2==1;};
 7 auto pos = std::find_if(begin, end, is_odd);
 8 if(pos != end)
 9 std::cout << *pos << std::endl;
10 }
11   
12 template <typename C>
13 void foo(C c)
14 {
15 bar(std::begin(c), std::end(c));
16 }
17   
18 template <typename T, size_t N>
19 void foo(T(&arr)[N])
20 {
21 bar(std::begin(arr), std::end(arr));
22 }
23   
24 int arr[] = {1,2,3};
25 foo(arr);
26   
27 std::vector<int> v;
28 v.push_back(1);
29 v.push_back(2);
30 v.push_back(3);
31 foo(v);

8.static_assert和type traits

static_assert是一个编译时断言检查。

用法:

1 static_assert(Size < 3, "Size is too small"); 

接下来是:

9Lambdas和Move语义,这两个都不太理解也没用过,留着慢慢研究下。。。。。

按照个人理解,move最简单的理解就是,直接将临时变量的数组指针拿来用,使得临时变量不需释放指针,而所构造的变量不需要重新分配用来存储数组的内存,更少了copy的过程。

move直接从字面意思就可以很契合的解释了,类似于财产转移,将自己名下的数组转移给构造的变量。

而一个变量是否可以用于财产(数组)转移,又需要标志,所以有右值引用(&&,左值引用为单&)的概念。

 

 

 

这篇随笔的例子都是copy过来,就做简单记录吧,说不定要用到,可以翻看下。

posted on 2013-07-28 12:59  DoubleZ  阅读(196)  评论(0)    收藏  举报

导航