C++11的变化-The Biggest Changes in C++11 (and Why You Should Care)

摘自:http://www.softwarequalityconnection.com/2011/06/the-biggest-changes-in-c11-and-why-you-should-care/

中文译文:http://blog.csdn.net/lanphaday/article/details/6564162

Bjarne Stroustrup, the creator of C++, said recently that C++11 “feels like a new language — the pieces just fit together better.” Indeed, core C++11 has changed significantly. It now supports lambda expressions, automatic type deduction of objects, uniform initialization syntax, delegating constructors, deleted and defaulted function declarations, nullptr, and most importantly, rvalue references — a feature that augurs a paradigm shift in how one conceives and handles objects. And that’s just a sample.

The C++11 Standard Library was also revamped with new algorithms, new container classes, atomic operations, type traits, regular expressions, new smart pointers, async() facility, and of course a multithreading library.

A complete list of the new core and library features of C++11 is available here.

After the approval of the C++ standard in 1998, two committee members prophesied that the next C++ standard would “certainly” include a built-in garbage collector (GC), and that it probably wouldn’t support multithreading because of the technical complexities involved in defining a portable threading model. Thirteen years later, the new C++ standard, C++11, is almost complete. Guess what? It lacks a GC but it does include a state-of–the-art threading library.

In this article I explain the biggest changes in the language, and why they are such a big deal. As you’ll see, threading libraries are not the only change. The new standard builds on the decades of expertise and makes C++ even more relevant. As Rogers Cadenhead points out, “That’s pretty amazing for something as old as disco, Pet Rocks, and Olympic swimmers with chest hair.”

First, let’s look at some of the prominent C++11 core-language features.

Lambda Expressions

A lambda expression lets you define functions locally, at the place of the call, thereby eliminating much of the tedium and security risks that function objects incur. A lambda expression has the form:

[capture](parameters)->return-type {body}

The [] construct inside a function call’s argument list indicates the beginning of a lambda expression. Let’s see a lambda example.

Suppose you want to count how many uppercase letters a string contains. Using for_each() to traverses a char array, the following lambda expression determines whether each letter is in uppercase. For every uppercase letter it finds, the lambda expression increments Uppercase, a variable defined outside the lambda expression:

int main()
{
   char s[]="Hello World!";
   int Uppercase = 0; //modified by the lambda
   for_each(s, s+sizeof(s), [&Uppercase] (char c) {
    if (isupper(c))
     Uppercase++;
    });
 cout<< Uppercase<<" uppercase letters in: "<< s<<endl;
}

It’s as if you defined a function whose body is placed inside another function call. The ampersand in [&Uppercase] means that the lambda body gets a reference to Uppercase so it can modify it. Without the ampersand, Uppercase would be passed by value. C++11 lambdas include constructs for member functions as well.

Automatic Type Deduction and decltype

In C++03, you must specify the type of an object when you declare it. Yet in many cases, an object’s declaration includes an initializer. C++11 takes advantage of this, letting you declare objects without specifying their types:

auto x=0; //x has type int because 0 is int
auto c='a'; //char
auto d=0.5; //double
auto national_debt=14400000000000LL;//long long

Automatic type deduction is chiefly useful when the type of the object is verbose or when it’s automatically generated (in templates). Consider:

void func(const vector<int> &vi)
{
vector<int>::const_iterator ci=vi.begin();
}

Instead, you can declare the iterator like this:

auto ci=vi.begin();

The keyword auto isn’t new; it actually dates back the pre-ANSI C era. However, C++11 has changed its meaning; auto no longer designates an object with automatic storage type. Rather, it declares an object whose type is deducible from its initializer. The old meaning of auto was removed from C++11 to avoid confusion.

C++11 offers a similar mechanism for capturing the type of an object or an expression. The new operator decltype takes an expression and “returns” its type:

const vector<int> vi;
typedef decltype (vi.begin()) CIT;
CIT another_const_iterator;

Uniform Initialization Syntax

C++ has at least four different initialization notations, some of which overlap.

Parenthesized initialization looks like this:

std::string s("hello");
int m=int(); //default initialization

You can also use the = notation for the same purpose in certain cases:

std::string s="hello";
int x=5;

For POD aggregates, you use braces:

int arr[4]={0,1,2,3};
struct tm today={0};

Finally, constructors use member initializers:

struct S {
 int x;
 S(): x(0) {} };

This proliferation is a fertile source for confusion, not only among novices. Worse yet, in C++03 you can’t initialize POD array members and POD arrays allocated using new[]. C++11 cleans up this mess with a uniform brace notation:

class C
{
int a;
int b;
public:
 C(int i, int j);
};

C c {0,0}; //C++11 only. Equivalent to: C c(0,0);

int* a = new int[3] { 1, 2, 0 }; /C++11 only

class X {
  int a[4];
public:
  X() : a{1,2,3,4} {} //C++11, member array initializer
};

With respect to containers, you can say goodbye to a long list of push_back() calls. In C++11 you can initialize containers intuitively:

// C++11 container initializer
vector<string> vs={ "first", "second", "third"};
map singers =
  { {"Lady Gaga", "+1 (212) 555-7890"},
    {"Beyonce Knowles", "+1 (212) 555-0987"}};

Similarly, C++11 supports in-class initialization of data members:

class C
{
 int a=7; //C++11 only
public:
 C();
};

Deleted and Defaulted Functions

A function in the form:

struct A
{
 A()=default; //C++11
 virtual ~A()=default; //C++11
};

is called a defaulted function. The =default; part instructs the compiler to generate the default implementation for the function. Defaulted functions have two advantages: They are more efficient than manual implementations, and they rid the programmer from the chore of defining those functions manually.

The opposite of a defaulted function is a deleted function:

int func()=delete;

Deleted functions are useful for preventing object copying, among the rest. Recall that C++ automatically declares a copy constructor and an assignment operator for classes. To disable copying, declare these two special member functions =delete:

struct NoCopy
{
    NoCopy & operator =( const NoCopy & ) = delete;
    NoCopy ( const NoCopy & ) = delete;
};
NoCopy a;
NoCopy b(a); //compilation error, copy ctor is deleted

nullptr

At last, C++ has a keyword that designates a null pointer constant. nullptr replaces the bug-prone NULL macro and the literal 0 that have been used as null pointer substitutes for many years.nullptr is strongly-typed:

void f(int); //#1
void f(char *);//#2
//C++03
f(0); //which f is called?
//C++11
f(nullptr) //unambiguous, calls #2

nullptr is applicable to all pointer categories, including function pointers and pointers to members:

const char *pc=str.c_str(); //data pointers
if (pc!=nullptr)
  cout<<pc<<endl;
int (A::*pmf)()=nullptr; //pointer to member function
void (*pmf)()=nullptr; //pointer to function

Delegating Constructors

In C++11 a constructor may call another constructor of the same class:

class M //C++11 delegating constructors
{
 int x, y;
 char *p;
public:
 M(int v) : x(v), y(0),  p(new char [MAX])  {} //#1 target
 M(): M(0) {cout<<"delegating ctor"<<endl;} //#2 delegating
};

Constructor #2, the delegating constructor, invokes the target constructor #1.

Rvalue References

Reference types in C++03 can only bind to lvalues. C++11 introduces a new category of reference types called rvalue references. Rvalue references can bind to rvalues, e.g. temporary objects and literals.

The primary reason for adding rvalue references is move semantics. Unlike traditional copying, moving means that a target object pilfers the resources of the source object, leaving the source in an “empty” state. In certain cases where making a copy of an object is both expensive and unnecessary, a move operation can be used instead. To appreciate the performance gains of move semantics, consider string swapping. A naive implementation would look like this:

void naiveswap(string &a, string & b)
{
 string temp = a;
 a=b;
 b=temp;
}

This is expensive. Copying a string entails the allocation of raw memory and copying the characters from the source to the target. In contrast, moving strings merely swaps two data members, without allocating memory, copying char arrays and deleting memory:

void moveswapstr(string& empty, string & filled)
{
//pseudo code, but you get the idea
 size_t sz=empty.size();
 const char *p= empty.data();
//move filled's resources to empty
 empty.setsize(filled.size());
 empty.setdata(filled.data());
//filled becomes empty
 filled.setsize(sz);
 filled.setdata(p);
}

If you’re implementing a class that supports moving, you can declare a move constructor and a move assignment operator like this:

class Movable
{
Movable (Movable&&); //move constructor
Movable&& operator=(Movable&&); //move assignment operator
};

The C++11 Standard Library uses move semantics extensively. Many algorithms and containers are now move-optimized.

C++11 Standard Library

C++ underwent a major facelift in 2003 in the form of the Library Technical Report 1 (TR1). TR1 included new container classes (unordered_setunordered_mapunordered_multiset, andunordered_multimap) and several new libraries for regular expressions, tuples, function object wrapper and more. With the approval of C++11, TR1 is officially incorporated into standard C++ standard, along with new libraries that have been added since TR1. Here are some of the C++11 Standard Library features:

THREADING LIBRARY

Unquestionably, the most important addition to C++11 from a programmer’s perspective is concurrency. C++11 has a thread class that represents an execution thread, promises and futures, which are objects that are used for synchronization in a concurrent environment, theasync() function template for launching concurrent tasks, and the thread_local storage type for declaring thread-unique data. For a quick tour of the C++11 threading library, read Anthony Williams’ Simpler Multithreading in C++0x.

NEW SMART POINTER CLASSES

C++98 defined only one smart pointer class, auto_ptr, which is now deprecated. C++11 includes new smart pointer classes: shared_ptr and the recently-added unique_ptr. Both are compatible with other Standard Library components, so you can safely store these smart pointers in standard containers and manipulate them with standard algorithms.

NEW ALGORITHMS

The C++11 Standard Library defines new algorithms that mimic the set theory operationsall_of()any_of() and none_of(). The following listing applies the predicate ispositive() to the range [first, first+n) and uses all_of()any_of() and none_of() to examine the range's properties:

#include <algorithm>
//C++11 code
//are all of the elements positive?
all_of(first, first+n, ispositive()); //false
//is there at least one positive element?
any_of(first, first+n, ispositive());//true
// are none of the elements positive?
none_of(first, first+n, ispositive()); //false

A new category of copy_n algorithms is also available. Using copy_n(), copying an array of 5 elements to another array is a cinch:

#include
int source[5]={0,12,34,50,80};
int target[5];
//copy 5 elements from source to target
copy_n(source,5,target);

The algorithm iota() creates a range of sequentially increasing values, as if by assigning an initial value to *first, then incrementing that value using prefix ++. In the following listing, iota()assigns the consecutive values {10,11,12,13,14} to the array arr, and {'a', 'b', 'c'} to the char arrayc.

include <numeric>
int a[5]={0};
char c[3]={0};
iota(a, a+5, 10); //changes a to {10,11,12,13,14}
iota(c, c+3, 'a'); //{'a','b','c'}

C++11 still lacks a few useful libraries such as an XML API, sockets, GUI, reflection — and yes, a proper automated garbage collector. However, it does offer plenty of new features that will make C++ more secure, efficient (yes, even more efficient than it has been thus far! See Google'sbenchmark tests), and easier to learn and use.

If the changes in C++11 seem overwhelming, don't be alarmed. Take the time to digest these changes gradually. At the end of this process you will probably agree with Stroustrup: C++11 doesfeel like a new language — a much better on


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
我搜索了一番,下面是世界上最大的100架飞机:1、波音747 2、空中客车A380 3、波音777 4、波音767 5、空中客车A340 6、波音787 7、英特尔斯A330 8、空中客车A320 9、英特尔斯A321 10、空中客车A319 11、英特尔斯A330-300 12、英特尔斯A330-200 13、 俄罗斯IL-86 14、空中客车A300 15、波音757 16、波音737 17、俄罗斯IL-96 18、空中客车A310 19、空中客车A300-600 20、波音737-800 21、俄罗斯TU-154 22、英特尔斯A340-300 23、空中客车A340-500 24、英特尔斯A340-600 25、波音737-700 26、俄罗斯TU-204 27、三菱MRJ90 28、俄罗斯IL-114 29、空中客车A330-500 30、英特尔斯A320neo 31、英特尔斯A321neo 32、空中客车A350-900 33、英特尔斯A330-900neo 34、波音737 MAX 9 35、英特尔斯A320ceo 36、空中客车A330-800neo 37、波音737 MAX 8 38、波音727 39、俄罗斯SU-80 40、英特尔斯A321LR 41、英特尔斯A321XLR 42、空中客车A350-1000 43、波音747-8 44、英特尔斯A318 45、英特尔斯A319neo 46、英特尔斯A220-100 47、英特尔斯A220-200 48、波音757-200 49、英特尔斯A330-1000neo 50、空中客车A320P2F 51、波音737 MAX 7 52、俄罗斯An-124 53、三菱MRJ70 54、波音727-200 55、英特尔斯A400M 56、空中客车ATR-72 57、空中客车ATR-42 58、俄罗斯TU-134 59、俄罗斯TU-154M 60、英特尔斯A330 MRTT 61、空中客车A321P2F 62、波音747-400 63、空中客车A340-200 64、波音737 MAX 10 65、波音777-300ER 66、英特尔斯A330-100 67、空中客车A330-300F 68、波音737-400 69、波音787-9 70、波音767-300ER 71、英特尔斯A340-500 72、空中客车A330-200F 73、波音767-400ER 74、俄罗斯An-225 75、波音777-200ER 76、波音777-200LR 77、空中客车A318 Elite 78、英特尔斯A330-200F 79、英特尔斯A350-800 80、波音757-300 81、波音767-200ER 82、空中客车A321neo ACF 83、空中客车A319ACJ 84、波音737 MAX 6 85、波音747-400F 86、波音737-500 87、英特尔斯A310-300 88、俄罗斯An-22 89、波音787-10 90、波音747-8F 91、波音737 MAX 5 92、空中客车A350-700 93、三菱MRJ90LR 94、波音747SP 95、俄罗斯SU-27 96、空中客车A320P2F 97、空中客车A330-700neo 98、俄罗斯TU-160 99、波音747-200 100、空中客车A320neo ACF

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值