# [cpp]What are move semantics?

http://stackoverflow.com/questions/3106110/what-are-move-semantics

I find it easiest to understand move semantics with example code. Let’s start with a very simple string class which only holds a pointer to a heap-allocated block of memory:

#include <cstring>
#include <algorithm>

class string
{
char* data;

public:

string(const char* p)
{
size_t size = strlen(p) + 1;
data = new char[size];
memcpy(data, p, size);
}

Since we chose to manage the memory ourselves, we need to follow the rule of three. I am going to defer writing the assignment operator and only implement the destructor and the copy constructor for now:

    ~string()
{
delete[] data;
}

string(const string& that)
{
size_t size = strlen(that.data) + 1;
data = new char[size];
memcpy(data, that.data, size);
}

The copy constructor defines what it means to copy string objects. The parameter const string& that binds to all expressions of type string which allows you to make copies in the following examples:

string a(x);                                    // Line 1
string b(x + y);                                // Line 2
string c(some_function_returning_a_string());   // Line 3

Now comes the key insight into move semantics. Note that only in the first line where we copy x is this deep copy really necessary, because we might want to inspect x later and would be very surprised if x had changed somehow. Did you notice how I just said x three times (four times if you include this sentence) and meant the exact same object every time? We call expressions such as x“lvalues”.

The arguments in lines 2 and 3 are not lvalues, but rvalues, because the underlying string objects have no names, so the client has no way to inspect them again at a later point in time. rvalues denote temporary objects which are destroyed at the next semicolon (to be more precise: at the end of the full-expression that lexically contains the rvalue). This is important because during the initialization of b and c, we could do whatever we wanted with the source string, and the client couldn’t tell a difference!

C++0x introduces a new mechanism called “rvalue reference” which, among other things, allows us to detect rvalue arguments via function overloading. All we have to do is write a constructor with an rvalue reference parameter. Inside that constructor we can do anything we want with the source, as long as we leave it in some valid state:

    string(string&& that)   // string&& is an rvalue reference to a string
{
data = that.data;
that.data = nullptr;
}

What have we done here? Instead of deeply copying the heap data, we have just copied the pointer and then set the original pointer to null. In effect, we have “stolen” the data that originally belonged to the source string. Again, the key insight is that under no circumstance could the client detect that the source had been modified. Since we don’t really do a copy here, we call this constructor a “move constructor”. Its job is to move resources from one object to another instead of copying them.

Congratulations, you now understand the basics of move semantics! Let’s continue by implementing the assignment operator. If you’re unfamiliar with the copy and swap idiom, learn it and come back, because it’s an awesome C++ idiom related to exception safety.

    string& operator=(string that)
{
std::swap(data, that.data);
return *this;
}
};

Huh, that’s it? “Where’s the rvalue reference?” you might ask. “We don’t need it here!” is my answer🙂

Note that we pass the parameter that by value, so that has to be initialized just like any other string object. Exactly how is that going to be initialized? In the olden days of C++98, the answer would have been “by the copy constructor”. In C++0x, the compiler chooses between the copy constructor and the move constructor based on whether the argument to the assignment operator is an lvalue or an rvalue.

So if you say a = b, the copy constructor will initialize that (because the expression b is an lvalue), and the assignment operator swaps the contents with a freshly created, deep copy. That is the very definition of the copy and swap idiom — make a copy, swap the contents with the copy, and then get rid of the copy by leaving the scope. Nothing new here.

But if you say a = x + y, the move constructor will initialize that (because the expression x + yis an rvalue), so there is no deep copy involved, only an efficient move. that is still an independent object from the argument, but its construction was trivial, since the heap data didn’t have to be copied, just moved. It wasn’t necessary to copy it because x + y is an rvalue, and again, it is okay to move from string objects denoted by rvalues.

To summarize, the copy constructor makes a deep copy, because the source must remain untouched. The move constructor, on the other hand, can just copy the pointer and then set the pointer in the source to null. It is okay to “nullify” the source object in this manner, because the client has no way of inspecting the object again.

I hope this example got the main point across. There is a lot more to rvalue references and move semantics which I intentionally left out to keep it simple. If you want more details please see my supplementary answer.

My first answer was an extremely simplified introduction to move semantics, and many details were left out on purpose to keep it simple. However, there is a lot more to move semantics, and I thought it was time for a second answer to fill the gaps. The first answer is already quite old, and it did not feel right to simply replace it with a completely different text. I think it still serves well as a first introduction. But if you want to dig deeper, read on🙂

Stephan T. Lavavej took the time provide valuable feedback. Thank you very much, Stephan!

## Introduction

Move semantics allows an object, under certain conditions, to take ownership of some other object’s external resources. This is important in two ways:

1. Turning expensive copies into cheap moves. See my first answer for an example. Note that if an object does not manage at least one external resource (either directly, or indirectly through its member objects), move semantics will not offer any advantages over copy semantics. In that case, copying an object and moving an object means the exact same thing:
class cannot_benefit_from_move_semantics
{
int a;        // moving an int means copying an int
float b;      // moving a float means copying a float
double c;     // moving a double means copying a double
char d[64];   // moving a char array means copying a char array

// ...
};
2. Implementing safe “move-only” types; that is, types for which copying does not make sense, but moving does. Examples include locks, file handles, and smart pointers with unique ownership semantics. Note: This answer discusses std::auto_ptr, a deprecated C++98 standard library template, which was replaced by std::unique_ptr in C++11. Intermediate C++ programmers are probably at least somewhat familiar with std::auto_ptr, and because of the “move semantics” it displays, it seems like a good starting point for discussing move semantics in C++11. YMMV.

## What is a move?

The C++98 standard library offers a smart pointer with unique ownership semantics called std::auto_ptr<T>. In case you are unfamiliar with auto_ptr, its purpose is to guarantee that a dynamically allocated object is always released, even in the face of exceptions:

{
std::auto_ptr<Shape> a(new Triangle);
// ...
// arbitrary code, could throw exceptions
// ...
}   // <--- when a goes out of scope, the triangle is deleted automatically

The unusual thing about auto_ptr is its “copying” behavior:

auto_ptr<Shape> a(new Triangle);

+---------------+
| triangle data |
+---------------+
^
|
|
|
+-----|---+
|   +-|-+ |
a | p | | | |
|   +---+ |
+---------+

auto_ptr<Shape> b(a);

+---------------+
| triangle data |
+---------------+
^
|
+----------------------+
|
+---------+            +-----|---+
|   +---+ |            |   +-|-+ |
a | p |   | |          b | p | | | |
|   +---+ |            |   +---+ |
+---------+            +---------+

Note how the initialization of b with a does not copy the triangle, but instead transfers the ownership of the triangle from a to b. We also say “a is moved into b” or “the triangle is moved from a to b“. This may sound confusing, because the triangle itself always stays at the same place in memory.

To move an object means to transfer ownership of some resource it manages to another object.

The copy constructor of auto_ptr probably looks something like this (somewhat simplified):

auto_ptr(auto_ptr& source)   // note the missing const
{
p = source.p;
source.p = 0;   // now the source no longer owns the object
}

## Dangerous and harmless moves

The dangerous thing about auto_ptr is that what syntactically looks like a copy is actually a move. Trying to call a member function on a moved-from auto_ptr will invoke undefined behavior, so you have to be very careful not to use an auto_ptr after it has been moved from:

auto_ptr<Shape> a(new Triangle);   // create triangle
auto_ptr<Shape> b(a);              // move a into b
double area = a->area();           // undefined behavior

But auto_ptr is not always dangerous. Factory functions are a perfectly fine use case for auto_ptr:

auto_ptr<Shape> make_triangle()
{
return auto_ptr<Shape>(new Triangle);
}

auto_ptr<Shape> c(make_triangle());      // move temporary into c
double area = make_triangle()->area();   // perfectly safe

Note how both examples follow the same syntactic pattern:

auto_ptr<Shape> variable(expression);
double area = expression->area();

And yet, one of them invokes undefined behavior, whereas the other one does not. So what is the difference between the expressions a and make_triangle()? Aren’t they both of the same type? Indeed they are, but they have different value categories.

## Value categories

Obviously, there must be some profound difference between the expression a which denotes an auto_ptr variable, and the expression make_triangle() which denotes the call of a function that returns an auto_ptr by value, thus creating a fresh temporary auto_ptr object every time it is called. a is an example of an lvalue, whereas make_triangle() is an example of an rvalue.

Moving from lvalues such as a is dangerous, because we could later try to call a member function via a, invoking undefined behavior. On the other hand, moving from rvalues such as make_triangle() is perfectly safe, because after the copy constructor has done its job, we cannot use the temporary again. There is no expression that denotes said temporary; if we simply write make_triangle() again, we get a different temporary. In fact, the moved-from temporary is already gone on the next line:

auto_ptr<Shape> c(make_triangle());
^ the moved-from temporary dies right here

Note that the letters l and r have a historic origin in the left-hand side and right-hand side of an assignment. This is no longer true in C++, because there are lvalues which cannot appear on the left-hand side of an assignment (like arrays or user-defined types without an assignment operator), and there are rvalues which can (all rvalues of class types with an assignment operator).

An rvalue of class type is an expression whose evaluation creates a temporary object. Under normal circumstances, no other expression inside the same scope denotes the same temporary object.

## Rvalue references

We now understand that moving from lvalues is potentially dangerous, but moving from rvalues is harmless. If C++ had language support to distinguish lvalue arguments from rvalue arguments, we could either completely forbid moving from lvalues, or at least make moving from lvalues explicit at call site, so that we no longer move by accident.

C++11’s answer to this problem is rvalue references. An rvalue reference is a new kind of reference that only binds to rvalues, and the syntax is X&&. The good old reference X& is now known as anlvalue reference. (Note that X&& is not a reference to a reference; there is no such thing in C++.)

If we throw const into the mix, we already have four different kinds of references. What kinds of expressions of type X can they bind to?

            lvalue   const lvalue   rvalue   const rvalue
---------------------------------------------------------
X&          yes
const X&    yes      yes            yes      yes
X&&                                 yes
const X&&                           yes      yes

In practice, you can forget about const X&&. Being restricted to read from rvalues is not very useful.

An rvalue reference X&& is a new kind of reference that only binds to rvalues.

## Implicit conversions

Rvalue references went through several versions. Since version 2.1, an rvalue reference X&& also binds to all value categories of a different type Y, provided there is an implicit conversion from Y to X. In that case, a temporary of type X is created, and the rvalue reference is bound to that temporary:

void some_function(std::string&& r);

some_function("hello world");

In the above example, "hello world" is an lvalue of type const char[12]. Since there is an implicit conversion from const char[12] through const char* to std::string, a temporary of type std::string is created, and r is bound to that temporary. This is one of the cases where the distinction between rvalues (expressions) and temporaries (objects) is a bit blurry.

## Move constructors

A useful example of a function with an X&& parameter is the move constructor X::X(X&& source). Its purpose is to transfer ownership of the managed resource from the source into the current object.

In C++11, std::auto_ptr<T> has been replaced by std::unique_ptr<T> which takes advantage of rvalue references. I will develop and discuss a simplified version of unique_ptr. First, we encapsulate a raw pointer and overload the operators -> and *, so our class feels like a pointer:

template<typename T>
class unique_ptr
{
T* ptr;

public:

T* operator->() const
{
return ptr;
}

T& operator*() const
{
return *ptr;
}

The constructor takes ownership of the object, and the destructor deletes it:

    explicit unique_ptr(T* p = nullptr)
{
ptr = p;
}

~unique_ptr()
{
delete ptr;
}

Now comes the interesting part, the move constructor:

    unique_ptr(unique_ptr&& source)   // note the rvalue reference
{
ptr = source.ptr;
source.ptr = nullptr;
}

This move constructor does exactly what the auto_ptr copy constructor did, but it can only be supplied with rvalues:

unique_ptr<Shape> a(new Triangle);
unique_ptr<Shape> b(a);                 // error
unique_ptr<Shape> c(make_triangle());   // okay

The second line fails to compile, because a is an lvalue, but the parameter unique_ptr&& sourcecan only be bound to rvalues. This is exactly what we wanted; dangerous moves should never be implicit. The third line compiles just fine, because make_triangle() is an rvalue. The move constructor will transfer ownership from the temporary to c. Again, this is exactly what we wanted.

The move constructor transfers ownership of a managed resource into the current object.

## Move assignment operators

The last missing piece is the move assignment operator. Its job is to release the old resource and acquire the new resource from its argument:

    unique_ptr& operator=(unique_ptr&& source)   // note the rvalue reference
{
if (this != &source)    // beware of self-assignment
{
delete ptr;         // release the old resource

ptr = source.ptr;   // acquire the new resource
source.ptr = nullptr;
}
return *this;
}
};

Note how this implementation of the move assignment operator duplicates logic of both the destructor and the move constructor. Are you familiar with the copy-and-swap idiom? It can also be applied to move semantics as the move-and-swap idiom:

    unique_ptr& operator=(unique_ptr source)   // note the missing reference
{
std::swap(ptr, source.ptr);
return *this;
}
};

Now that source is a variable of type unique_ptr, it will be initialized by the move constructor; that is, the argument will be moved into the parameter. The argument is still required to be an rvalue, because the move constructor itself has an rvalue reference parameter. When control flow reaches the closing brace of operator=, source goes out of scope, releasing the old resource automatically.

The move assignment operator transfers ownership of a managed resource into the current object, releasing the old resource. The move-and-swap idiom simplifies the implementation.

## Moving from lvalues

Sometimes, we want to move from lvalues. That is, sometimes we want the compiler to treat an lvalue as if it were an rvalue, so it can invoke the move constructor, even though it could be potentially unsafe. For this purpose, C++11 offers a standard library function template called std::move inside the header <utility>. This name is a bit unfortunate, because std::move simply casts an lvalue to an rvalue; it does not move anything by itself. It merely enables moving. Maybe it should have been named std::cast_to_rvalue or std::enable_move, but we are stuck with the name by now.

Here is how you explicitly move from an lvalue:

unique_ptr<Shape> a(new Triangle);
unique_ptr<Shape> b(a);              // still an error
unique_ptr<Shape> c(std::move(a));   // okay

Note that after the third line, a no longer owns a triangle. That’s okay, because by explicitly writing std::move(a), we made our intentions clear: “Dear constructor, do whatever you want with a in order to initialize c; I don’t care about a anymore. Feel free to have your way with a.”

std::move(some_lvalue) casts an lvalue to an rvalue, thus enabling a subsequent move.

## Xvalues

Note that even though std::move(a) is an rvalue, its evaluation does not create a temporary object. This conundrum forced the committee to introduce a third value category. Something that can be bound to an rvalue reference, even though it is not an rvalue in the traditional sense, is called anxvalue (eXpiring value). The traditional rvalues were renamed to prvalues (Pure rvalues).

Both prvalues and xvalues are rvalues. Xvalues and lvalues are both glvalues (Generalized lvalues). The relationships are easier to grasp with a diagram:

        expressions
/     \
/       \
/         \
glvalues   rvalues
/  \       /  \
/    \     /    \
/      \   /      \
lvalues   xvalues   prvalues

Note that only xvalues are really new; the rest is just due to renaming and grouping.

C++98 rvalues are known as prvalues in C++11. Mentally replace all occurrences of “rvalue” in the preceding paragraphs with “prvalue”.

## Moving out of functions

So far, we have seen movement into local variables, and into function parameters. But moving is also possible in the opposite direction. If a function returns by value, some object at call site (probably a local variable or a temporary, but could be any kind of object) is initialized with the expression after thereturn statement as an argument to the move constructor:

unique_ptr<Shape> make_triangle()
{
return unique_ptr<Shape>(new Triangle);
}          \-----------------------------/
|
| temporary is moved into c
|
v
unique_ptr<Shape> c(make_triangle());

Perhaps surprisingly, automatic objects (local variables that are not declared as static) can also beimplicitly moved out of functions:

unique_ptr<Shape> make_square()
{
unique_ptr<Shape> result(new Square);
return result;   // note the missing std::move
}

How come the move constructor accepts the lvalue result as an argument? The scope of resultis about to end, and it will be destroyed during stack unwinding. Nobody could possibly complain afterwards that result had changed somehow; when control flow is back at the caller, result does not exist anymore! For that reason, C++11 has a special rule that allows returning automatic objects from functions without having to write std::move. In fact, you should never use std::move to move automatic objects out of functions, as this inhibits the “named return value optimization” (NRVO).

Never use std::move to move automatic objects out of functions.

Note that in both factory functions, the return type is a value, not an rvalue reference. Rvalue references are still references, and as always, you should never return a reference to an automatic object; the caller would end up with a dangling reference if you tricked the compiler into accepting your code, like this:

unique_ptr<Shape>&& flawed_attempt()   // DO NOT DO THIS!
{
}

Never return automatic objects by rvalue reference. Moving is exclusively performed by the move constructor, not by std::move, and not by merely binding an rvalue to an rvalue reference.

## Moving into members

Sooner or later, you are going to write code like this:

class Foo
{
unique_ptr<Shape> member;

public:

Foo(unique_ptr<Shape>&& parameter)
: member(parameter)   // error
{}
};

Basically, the compiler will complain that parameter is an lvalue. If you look at its type, you see an rvalue reference, but an rvalue reference simply means “a reference that is bound to an rvalue”; it does not mean that the reference itself is an rvalue! Indeed, parameter is just an ordinary variable with a name. You can use parameter as often as you like inside the body of the constructor, and it always denotes the same object. Implicitly moving from it would be dangerous, hence the language forbids it.

A named rvalue reference is an lvalue, just like any other variable.

The solution is to manually enable the move:

class Foo
{
unique_ptr<Shape> member;

public:

Foo(unique_ptr<Shape>&& parameter)
: member(std::move(parameter))   // note the std::move
{}
};

You could argue that parameter is not used anymore after the initialization of member. Why is there no special rule to silently insert std::move just as with return values? Probably because it would be too much burden on the compiler implementors. For example, what if the constructor body was in another translation unit? By contrast, the return value rule simply has to check the symbol tables to determine whether or not the identifier after the return keyword denotes an automatic object.

You can also pass parameter by value. For move-only types like unique_ptr, it seems there is no established idiom yet. Personally, I prefer pass by value, as it causes less clutter in the interface.

## Special member functions

C++98 implicitly declares three special member functions on demand, that is, when they are needed somewhere: the copy constructor, the copy assignment operator and the destructor.

X::X(const X&);              // copy constructor
X& X::operator=(const X&);   // copy assignment operator
X::~X();                     // destructor

Rvalue references went through several versions. Since version 3.0, C++11 declares two additional special member functions on demand: the move constructor and the move assignment operator. Note that neither VC10 nor VC11 conform to version 3.0 yet, so you will have to implement them yourself.

X::X(X&&);                   // move constructor
X& X::operator=(X&&);        // move assignment operator

These two new special member functions are only implicitly declared if none of the special member functions are declared manually. Also, if you declare your own move constructor or move assignment operator, neither the copy constructor nor the copy assignment operator will be declared implicitly.

What do these rules mean in practice?

If you write a class without unmanaged resources, there is no need to declare any of the five special member functions yourself, and you will get correct copy semantics and move semantics for free. Otherwise, you will have to implement the special member functions yourself. Of course, if your class does not benefit from move semantics, there is no need to implement the special move operations.

Note that the copy assignment operator and the move assignment operator can be fused into a single, unified assignment operator, taking its argument by value:

X& X::operator=(X source)    // unified assignment operator
{
swap(source);            // see my first answer for an explanation
return *this;
}

This way, the number of special member functions to implement drops from five to four. There is a tradeoff between exception-safety and efficiency here, but I am not an expert on this issue.

## Forwarding references (previouslyknown asUniversal references)

Consider the following function template:

template<typename T>
void foo(T&&);

You might expect T&& to only bind to rvalues, because at first glance, it looks like an rvalue reference. As it turns out though, T&& also binds to lvalues:

foo(make_triangle());   // T is unique_ptr<Shape>, T&& is unique_ptr<Shape>&&
unique_ptr<Shape> a(new Triangle);
foo(a);                 // T is unique_ptr<Shape>&, T&& is unique_ptr<Shape>&

If the argument is an rvalue of type X, T is deduced to be X, hence T&& means X&&. This is what anyone would expect. But if the argument is an lvalue of type X, due to a special rule, T is deduced to be X&, hence T&& would mean something like X& &&. But since C++ still has no notion of references to references, the type X& && is collapsed into X&. This may sound confusing and useless at first, but reference collapsing is essential for perfect forwarding (which will not be discussed here).

T&& is not an rvalue reference, but a forwarding reference. It also binds to lvalues, in which case T and T&& are both lvalue references.

If you want to constrain a function template to rvalues, you can combine SFINAE with type traits:

#include <type_traits>

template<typename T>
typename std::enable_if<std::is_rvalue_reference<T&&>::value, void>::type
foo(T&&);

## Implementation of move

Now that you understand reference collapsing, here is how std::move is implemented:

template<typename T>
typename std::remove_reference<T>::type&&
move(T&& t)
{
return static_cast<typename std::remove_reference<T>::type&&>(t);
}

As you can see, move accepts any kind of parameter thanks to the forwarding reference T&&, and it returns an rvalue reference. The std::remove_reference<T>::type meta-function call is necessary because otherwise, for lvalues of type X, the return type would be X& &&, which would collapse into X&. Since t is always an lvalue (remember that a named rvalue reference is an lvalue), but we want to bind t to an rvalue reference, we have to explicitly cast t to the correct return type. The call of a function that returns an rvalue reference is itself an xvalue. Now you know where xvalues come from😉

The call of a function that returns an rvalue reference, such as std::move, is an xvalue.

Note that returning by rvalue reference is fine in this example, because t does not denote an automatic object, but instead an object that was passed in by the caller.

# [cpp]What is the copy-and-swap idiom?

## Overview

### Why do we need the copy-and-swap idiom?

Any class that manages a resource (a wrapper, like a smart pointer) needs to implement The Big Three. While the goals and implementation of the copy-constructor and destructor are straightforward, the copy-assignment operator is arguably the most nuanced and difficult. How should it be done? What pitfalls need to be avoided?

The copy-and-swap idiom is the solution, and elegantly assists the assignment operator in achieving two things: avoiding code duplication, and providing a strong exception guarantee.

### How does it work?

Conceptually, it works by using the copy-constructor’s functionality to create a local copy of the data, then takes the copied data with a swap function, swapping the old data with the new data. The temporary copy then destructs, taking the old data with it. We are left with a copy of the new data.

In order to use the copy-and-swap idiom, we need three things: a working copy-constructor, a working destructor (both are the basis of any wrapper, so should be complete anyway), and a swapfunction.

A swap function is a non-throwing function that swaps two objects of a class, member for member. We might be tempted to use std::swap instead of providing our own, but this would be impossible; std::swap uses the copy-constructor and copy-assignment operator within its implementation, and we’d ultimately be trying to define the assignment operator in terms of itself!

(Not only that, but unqualified calls to swap will use our custom swap operator, skipping over the unnecessary construction and destruction of our class that std::swap would entail.)

## An in-depth explanation

### The goal

Let’s consider a concrete case. We want to manage, in an otherwise useless class, a dynamic array. We start with a working constructor, copy-constructor, and destructor:

#include <algorithm> // std::copy
#include <cstddef> // std::size_t

class dumb_array
{
public:
// (default) constructor
dumb_array(std::size_t size = 0)
: mSize(size),
mArray(mSize ? new int[mSize]() : 0)
{
}

// copy-constructor
dumb_array(const dumb_array& other)
: mSize(other.mSize),
mArray(mSize ? new int[mSize] : 0),
{
// note that this is non-throwing, because of the data
// types being used; more attention to detail with regards
// to exceptions must be given in a more general case, however
std::copy(other.mArray, other.mArray + mSize, mArray);
}

// destructor
~dumb_array()
{
delete [] mArray;
}

private:
std::size_t mSize;
int* mArray;
};

This class almost manages the array successfully, but it needs operator= to work correctly.

### A failed solution

Here’s how a naive implementation might look:

// the hard part
dumb_array& operator=(const dumb_array& other)
{
if (this != &other) // (1)
{
// get rid of the old data...
delete [] mArray; // (2)
mArray = 0; // (2) *(see footnote for rationale)

// ...and put in the new
mSize = other.mSize; // (3)
mArray = mSize ? new int[mSize] : 0; // (3)
std::copy(other.mArray, other.mArray + mSize, mArray); // (3)
}

return *this;
}

And we say we’re finished; this now manages an array, without leaks. However, it suffers from three problems, marked sequentially in the code as (n).

1. The first is the self-assignment test. This check serves two purposes: it’s an easy way to prevent us from running needless code on self-assignment, and it protects us from subtle bugs (such as deleting the array only to try and copy it). But in all other cases it merely serves to slow the program down, and act as noise in the code; self-assignment rarely occurs, so most of the time this check is a waste. It would be better if the operator could work properly without it.
2. The second is that it only provides a basic exception guarantee. If new int[mSize] fails, *thiswill have been modified. (Namely, the size is wrong and the data is gone!) For a strong exception guarantee, it would need to be something akin to:
dumb_array& operator=(const dumb_array& other)
{
if (this != &other) // (1)
{
// get the new data ready before we replace the old
std::size_t newSize = other.mSize;
int* newArray = newSize ? new int[newSize]() : 0; // (3)
std::copy(other.mArray, other.mArray + newSize, newArray); // (3)

// replace the old data (all are non-throwing)
delete [] mArray;
mSize = newSize;
mArray = newArray;
}

return *this;
}
3. The code has expanded! Which leads us to the third problem: code duplication. Our assignment operator effectively duplicates all the code we’ve already written elsewhere, and that’s a terrible thing.

In our case, the core of it is only two lines (the allocation and the copy), but with more complex resources this code bloat can be quite a hassle. We should strive to never repeat ourselves.

(One might wonder: if this much code is needed to manage one resource correctly, what if my class manages more than one? While this may seem to be a valid concern, and indeed it requires non-trivialtry/catch clauses, this is a non-issue. That’s because a class should manage one resource only!)

### A successful solution

As mentioned, the copy-and-swap idiom will fix all these issues. But right now, we have all the requirements except one: a swap function. While The Rule of Three successfully entails the existence of our copy-constructor, assignment operator, and destructor, it should really be called “The Big Three and A Half”: any time your class manages a resource it also makes sense to provide a swap function.

We need to add swap functionality to our class, and we do that as follows†:

class dumb_array
{
public:
// ...

friend void swap(dumb_array& first, dumb_array& second) // nothrow
{
// enable ADL (not necessary in our case, but good practice)
using std::swap;

// by swapping the members of two classes,
// the two classes are effectively swapped
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray);
}

// ...
};

Now not only can we swap our dumb_array‘s, but swaps in general can be more efficient; it merely swaps pointers and sizes, rather than allocating and copying entire arrays. Aside from this bonus in functionality and efficiency, we are now ready to implement the copy-and-swap idiom.

Without further ado, our assignment operator is:

dumb_array& operator=(dumb_array other) // (1)
{
swap(*this, other); // (2)

return *this;
}

And that’s it! With one fell swoop, all three problems are elegantly tackled at once.

### Why does it work?

We first notice an important choice: the parameter argument is taken by-value. While one could just as easily do the following (and indeed, many naive implementations of the idiom do):

dumb_array& operator=(const dumb_array& other)
{
dumb_array temp(other);
swap(*this, temp);

return *this;
}

We lose an important optimization opportunity. Not only that, but this choice is critical in C++11, which is discussed later. (On a general note, a remarkably useful guideline is as follows: if you’re going to make a copy of something in a function, let the compiler do it in the parameter list.‡)

Either way, this method of obtaining our resource is the key to eliminating code duplication: we get to use the code from the copy-constructor to make the copy, and never need to repeat any bit of it. Now that the copy is made, we are ready to swap.

Observe that upon entering the function that all the new data is already allocated, copied, and ready to be used. This is what gives us a strong exception guarantee for free: we won’t even enter the function if construction of the copy fails, and it’s therefore not possible to alter the state of *this. (What we did manually before for a strong exception guarantee, the compiler is doing for us now; how kind.)

At this point we are home-free, because swap is non-throwing. We swap our current data with the copied data, safely altering our state, and the old data gets put into the temporary. The old data is then released when the function returns. (Where upon the parameter’s scope ends and its destructor is called.)

Because the idiom repeats no code, we cannot introduce bugs within the operator. Note that this means we are rid of the need for a self-assignment check, allowing a single uniform implementation of operator=. (Additionally, we no longer have a performance penalty on non-self-assignments.)

And that is the copy-and-swap idiom.

The next version of C++, C++11, makes one very important change to how we manage resources: the Rule of Three is now The Rule of Four (and a half). Why? Because not only do we need to be able to copy-construct our resource, we need to move-construct it as well.

Luckily for us, this is easy:

class dumb_array
{
public:
// ...

// move constructor
dumb_array(dumb_array&& other)
: dumb_array() // initialize via default constructor, C++11 only
{
swap(*this, other);
}

// ...
};

What’s going on here? Recall the goal of move-construction: to take the resources from another instance of the class, leaving it in a state guaranteed to be assignable and destructible.

So what we’ve done is simple: initialize via the default constructor (a C++11 feature), then swap with other; we know a default constructed instance of our class can safely be assigned and destructed, so we know other will be able to do the same, after swapping.

(Note that some compilers do not support constructor delegation; in this case, we have to manually default construct the class. This is an unfortunate but luckily trivial task.)

### Why does that work?

That is the only change we need to make to our class, so why does it work? Remember the ever-important decision we made to make the parameter a value and not a reference:

dumb_array& operator=(dumb_array other); // (1)

Now, if other is being initialized with an rvalue, it will be move-constructed. Perfect. In the same way C++03 let us re-use our copy-constructor functionality by taking the argument by-value, C++11 willautomatically pick the move-constructor when appropriate as well. (And, of course, as mentioned in previously linked article, the copying/moving of the value may simply be elided altogether.)

And so concludes the copy-and-swap idiom.

### Footnotes

*Why do we set mArray to null? Because if any further code in the operator throws, the destructor of dumb_array might be called; and if that happens without setting it to null, we attempt to delete memory that’s already been deleted! We avoid this by setting it to null, as deleting null is a no-operation.

†There are other claims that we should specialize std::swap for our type, provide an in-class swapalong-side a free-function swap, etc. But this is all unnecessary: any proper use of swap will be through an unqualified call, and our function will be found through ADL. One function will do.

‡The reason is simple: once you have the resource to yourself, you may swap and/or move it (C++11) anywhere it needs to be. And by making the copy in the parameter list, you maximize optimization.

# [cpp]What is The Rule of Three?

http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three

https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

# Introduction

C++ treats variables of user-defined types with value semantics. This means that objects are implicitly copied in various contexts, and we should understand what “copying an object” actually means.

Let us consider a simple example:

class person
{
std::string name;
int age;

public:

person(const std::string& name, int age) : name(name), age(age)
{
}
};

int main()
{
person a("Bjarne Stroustrup", 60);
person b(a);   // What happens here?
b = a;         // And here?
}

(If you are puzzled by the name(name), age(age) part, this is called a member initializer list.)

# Special member functions

What does it mean to copy a person object? The main function shows two distinct copying scenarios. The initialization person b(a); is performed by the copy constructor. Its job is to construct a fresh object based on the state of an existing object. The assignment b = a is performed by the copy assignment operator. Its job is generally a little more complicated, because the target object is already in some valid state that needs to be dealt with.

Since we declared neither the copy constructor nor the assignment operator (nor the destructor) ourselves, these are implicitly defined for us. Quote from the standard:

The […] copy constructor and copy assignment operator, […] and destructor are special member functions. [ Note: The implementation will implicitly declare these member functions for some class types when the program does not explicitly declare them. The implementation will implicitly define them if they are used. […] end note ] [n3126.pdf section 12 §1]

By default, copying an object means copying its members:

The implicitly-defined copy constructor for a non-union class X performs a memberwise copy of its subobjects. [n3126.pdf section 12.8 §16]

The implicitly-defined copy assignment operator for a non-union class X performs memberwise copy assignment of its subobjects. [n3126.pdf section 12.8 §30]

## Implicit definitions

The implicitly-defined special member functions for person look like this:

// 1. copy constructor
person(const person& that) : name(that.name), age(that.age)
{
}

// 2. copy assignment operator
person& operator=(const person& that)
{
name = that.name;
age = that.age;
return *this;
}

// 3. destructor
~person()
{
}

Memberwise copying is exactly what we want in this case: name and age are copied, so we get a self-contained, independent person object. The implicitly-defined destructor is always empty. This is also fine in this case since we did not acquire any resources in the constructor. The members’ destructors are implicitly called after the person destructor is finished:

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct […] members [n3126.pdf 12.4 §6]

# Managing resources

So when should we declare those special member functions explicitly? When our class manages a resource, that is, when an object of the class is responsible for that resource. That usually means the resource is acquired in the constructor (or passed into the constructor) and released in the destructor.

Let us go back in time to pre-standard C++. There was no such thing as std::string, and programmers were in love with pointers. The person class might have looked like this:

class person
{
char* name;
int age;

public:

// the constructor acquires a resource:
// in this case, dynamic memory obtained via new[]
person(const char* the_name, int the_age)
{
name = new char[strlen(the_name) + 1];
strcpy(name, the_name);
age = the_age;
}

// the destructor must release this resource via delete[]
~person()
{
delete[] name;
}
};

Even today, people still write classes in this style and get into trouble: “I pushed a person into a vector and now I get crazy memory errors!” Remember that by default, copying an object means copying its members, but copying the name member merely copies a pointer, not the character array it points to! This has several unpleasant effects:

1. Changes via a can be observed via b.
2. Once b is destroyed, a.name is a dangling pointer.
3. If a is destroyed, deleting the dangling pointer yields undefined behavior.
4. Since the assignment does not take into account what name pointed to before the assignment, sooner or later you will get memory leaks all over the place.

## Explicit definitions

Since memberwise copying does not have the desired effect, we must define the copy constructor and the copy assignment operator explicitly to make deep copies of the character array:

// 1. copy constructor
person(const person& that)
{
name = new char[strlen(that.name) + 1];
strcpy(name, that.name);
age = that.age;
}

// 2. copy assignment operator
person& operator=(const person& that)
{
if (this != &that)
{
delete[] name;
// This is a dangerous point in the flow of execution!
// We have temporarily invalidated the class invariants,
// and the next statement might throw an exception,
// leaving the object in an invalid state :(
name = new char[strlen(that.name) + 1];
strcpy(name, that.name);
age = that.age;
}
return *this;
}

Note the difference between initialization and assignment: we must tear down the old state before assigning to name to prevent memory leaks. Also, we have to protect against self-assignment of the form x = x. Without that check, delete[] name would delete the array containing the source string, because when you write x = x, both this->name and that.name contain the same pointer.

## Exception safety

Unfortunately, this solution will fail if new char[...] throws an exception due to memory exhaustion. One possible solution is to introduce a local variable and reorder the statements:

// 2. copy assignment operator
person& operator=(const person& that)
{
char* local_name = new char[strlen(that.name) + 1];
// If the above statement throws,
// the object is still in the same state as before.
// None of the following statements will throw an exception :)
strcpy(local_name, that.name);
delete[] name;
name = local_name;
age = that.age;
return *this;
}

This also takes care of self-assignment without an explicit check. An even more robust solution to this problem is the copy-and-swap idiom, but I will not go into the details of exception safety here. I only mentioned exceptions to make the following point: Writing classes that manage resources is hard.

## Noncopyable resources

Some resources cannot or should not be copied, such as file handles or mutexes. In that case, simply declare the copy constructor and copy assignment operator as private without giving a definition:

private:

person(const person& that);
person& operator=(const person& that);

Alternatively, you can inherit from boost::noncopyable or declare them as deleted (C++0x):

person(const person& that) = delete;
person& operator=(const person& that) = delete;

## The rule of three

Sometimes you need to implement a class that manages a resource. (Never manage multiple resources in a single class, this will only lead to pain.) In that case, remember the rule of three:

If you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them.

(Unfortunately, this “rule” is not enforced by the C++ standard or any compiler I am aware of.)

Most of the time, you do not need to manage a resource yourself, because an existing class such as std::string already does it for you. Just compare the simple code using a std::string member to the convoluted and error-prone alternative using a char* and you should be convinced. As long as you stay away from raw pointer members, the rule of three is unlikely to concern your own code.

# [fwd]详解小米电视新增加的DTMB功能

 2014年后出厂的小米电视新增加DTMB功能，很多粉友不太了解这个DTMB功能是什么作用，DTMB是国家制定的地面数字电视广播传输标准，实现了固定电视和公共交通移动电视的数字电视信号传送。DTMB于2007年8月1号成为中国广播业地面电视信号的强制标准。 DTMB，全称Digital TelevisionTerrestrial Multimedia Broadcasting（中文：地面数字电视广播） 在数字电视地面、有线、卫星传输方式中，数字电视地面传输系统环境最为复杂，也因其技术要求最高、受众广而备受关注。地面系统的标准化工作也十分重要。目 前已有美国高级电视系统委员会（ATSC）、欧洲数字视频地面广播（DVB-T）和日本地面综合业务数字广播（ISDB-T）三个国际电联批准的地面数字 电视广播传输国际标准。1999年我国设立数字电视研发及产业化并成立国家数字电视领导小组，明确宣示自主制定技术标准。针对我国数字电视应用的具体标 准，2006年推出了我国数字电视地面标准DTMB。 在国家广播电影电视总局支持下，我国于2006年8月18 日正式颁布了《数字电视地面广播传输系统帧结构、信道编码和调制》(GB20600-2006)地面数字电视广播传输标准，实现了固定电视和公共交通移动 电视的数字电视信号传送。DTMB于2007年8月1号成为中国广播业地面电视信号的强制标准。 DTMB 系统能有效支持包括高清晰度电视（HDTV）、标清电视（SDTV）和多媒体数据广播等多种业务，同时完全满足大范围固定覆盖和移动接收需要。2007年 6月4日，香港电信管理局（OFTA）正式宣布从7月1日起采用DTMB进行试播。2009年，澳门也宣布了将采用与香港相同模式进行播出的计划。 2008年1月1日起国内多个城市开始了DTMB试播。奥运期间，7个奥运比赛城市播出了HDTV节目，为DTMB的大范围推广积累了经验。 地面数字电视是数字电视技术的一种，即通过接受电视塔发出的地面数字电视信号，收看电视节目。 % Q# J4 l( B+ m5 a  h0 v4 R 上面的资料我们知道DTMB是地面数字电视信号标准，那什么是地面数字 电视信号？我们知道数字电视技术主要分为地面数字电视、卫星数字电视和有线数字电视三种，其中地面数字电视信号是电视节目频道通过信号发射塔以地面波的方 法传输，信号覆盖范围内的用户可架设接收天线接收到地面数字电视信号。 那DTMB数字电视信号怎样才能接收到呢？ 1. 首先要确定当地的电视信号发射塔发出（不是每个地方的电视信号发射塔发出的信号都是DTMB数字电视信号，还有很多地方还是模拟电视信号），并在信号覆盖 范围之内（覆盖范围要视乎信号发射塔的发射功率和地形环境），目前主要大城市地面电视信号已经转换为DTMB数字电视信号。 2.用户端接收需要支持DTMB制式的机顶盒或支持DTMB制式的电视，另外还要接收天线，接收天线根据当地的信号质量选择合适的类型 信号比较弱的地区还需要另外增加信号放大器 我的小米电视是2013年10月15号首批抢到的，我们当地能接收到香港和深圳发出 的DTMB高清数字电视信号，为了感受小米电视的高清大屏，还专门另外购买了支持DTMB的机顶，2014年后抢购到小米电视并当地有DTMB数字电视信 号覆盖的就可以省略这个机顶盒。那DTMB数字电视信号有什么特点和功能呢？因为我的小米电视没有DTMB功能，我只有用我的DTMB机顶盒给大家简单介 绍一下 我在楼顶架起的接收天线 支持DTMB高清数字电视信号的机顶盒，机顶盒通过HDMI接口跟小米电视连接 显示DTMB信号接收信息，这个能功很重要，方便调节接收天线 我这里能接收到的电视节目 原版高质量16:9 + 1080p高清画面 电视频道的电子节目单和节目内容介绍 支持多音轨选择和杜比AC-3音频编号 支持多字幕选择 支持节目预约录制，不担心错过精彩节目 还有DTMB信号发射接收是完全免费的。 另外有粉友问小米电视新增加的DTMB功能可以支持广电有线数字电视信号，代替广电的机顶盒吗? 答案是：广电有线方式传输的数字电视信号是DVB-C制式加密传输，需要配置广电专用的机顶盒和IC卡收看，所以小米电视新增加的DTMB制式并不支持广电有线的数字电视信号，想取代广电有线机顶盒还需要等待小米之前发布的“迷你高清数字电视盒”。

# [fwd]Android 音频系统

http://blog.csdn.net/qianjin0703/article/details/6387662

0. 专用术语

1. 物理结构

2. 系统架构

0. 专用术语

ASLA – Advanced Sound Linux Architecture

OSS – 以前的Linux音频体系结构，被ASLA取代并兼容

Codec – Coder/Decoder

I2S/PCM/AC97 – Codec与CPU间音频的通信协议/接口/总线

DAI – Digital Audio Interface 其实就是I2S/PCM/AC97

DAC – Digit to Analog Conversion

ADC – Analog to Digit Conversion

DSP – Digital Signal Processor

Mixer – 混音器，将来自不同通道的几种音频模拟信号混合成一种模拟信号

Mute – 消音，屏蔽信号通道

PCM – Pulse Code Modulation 一种从音频模拟信号转换成数字信号的技术，区别于PCM音频通信协议

量化精度 – 比如24bit，就是将音频模拟信号按照2的24次方进行等分

SSI – Serial Sound Interface

DAPM – Dynamic Audio Power Management

1. 物理结构

Codec与处理器之间通过I2C总线和数字音频接口DAI进行通信。

I2C总线 – 实现对Codec寄存器数据的读写。

DAI – 实现音频数据在CPU和Codec间的通信。

1) 播放音乐

2) 录音

3) 电话

— 打电话 —                                                           — 接听—

4) 通过蓝牙打电话

— 打电话 —                                                           — 接听—

2. 系统架构

Android的音频系统拥有一个比较标准和健全的架构，从上层应用，java framework服务AudioMananger，本地服务AudioFlinger，抽象层AlsaHAL，本地库，再调用external的 Alsa-lib外部支持库，最后到底层驱动的codec，可谓”五脏俱全”。

以系统启动AuidoFlinger为例，简要窥探Alsa Sound的组织架构。

Linux的音频驱动结构相对复杂，源码位于内核目录下的/sound/soc/，其中/codec文件夹下存放与平台无关的编解码器驱动，/imx文件夹下存放于freescale imx平台相关的音频驱动，主要可分为SSI驱动和DAI驱动。

1) struct snd_soc_codec – 由与平台无关的codec驱动实现。

2) struct snd_soc_platform – 由与imx平台相关的DAI驱动实现，主要实现了音频数据的DMA传输功能。

# 球坐标系

下图描述了球坐标的几何意义：原点O与目标点P之间的径向距离为r，O到P的连线与正z-轴之间的夹角为天顶角θ，O到P的连线在xy-平面上的投影线与正x-轴之间的夹角为方位角φ

# 三维空间下直角坐标与球坐标的相互转换

${r}=\sqrt{x^2 + y^2 + z^2}$ 、

${\theta}=\arctan \left( \frac{\sqrt{x^2 + y^2}}{z} \right)=\arccos \left( {\frac{z}{\sqrt{x^2 + y^2 + z^2}}} \right)$ 、

${\phi}=\arctan \left( {\frac{y}{x}} \right)$ 。

$x=r \sin\theta \cos\phi$ 、

$y=r \sin\theta \sin\phi$ 、

$z=r \cos\theta$ 。

# [fwd]齐次坐标的理解

LJ注：统一向量与点？

http://www.cnblogs.com/csyisong/archive/2008/12/09/1351372.html

(1)(3)是坐标系下表达一个向量和点的不同表达方式。这里可以看出，虽然都是用代数分量的形式表达向量和点，但表达一个点比一个向量需要额外的信息。如果我写出一个代数分量表达(1, 4, 7)，谁知道它是个向量还是个点！

p = (p1 p2 p3 1) X (a b c o),这里(a,b,c,o)是坐标基矩阵，右边的列向量分别是向量v和点p在基下的坐标。这样，向量和点在同一个基下就有了不同的表达：3D向量的第4个代数分量是0，而3D点的第4个代数分量是1。像这种这种用4个代数分量表示3D几何概念的方式是一种齐次坐标表示。

(1)从普通坐标转换成齐次坐标时

(2)从齐次坐标转换成普通坐标时

# [fwd]install vs. cp; and mmap

1.系统使用mmap的方式映射binary executables 和 shared libraries来运行

http://en.chys.info/2009/05/install-vs-cp-and-mmap/

If we hand write a Makefile, we should always stick to install instead of using cp for the installation commands. Not only is it more convenient, but it does things right (cp does things wrong).

For example, if we attempt to update /bin/bash, which is currently running, with “cp ... /bin/bash”, we get a “text busy” error. If we attempt to update /lib/libc.so.6 with “cp ... /lib/libc.so.6”, then we either get “text busy” (in ancient versions of Linux) or breaks each and every running program within a fraction of a second (in recent versions of Linux). install does the thing right in both situations.

The reason why cp fails is that it simply attempts to open the destination file in write-only mode and write the new contents. This causes problem because Linux (and all contemporary Unices as well as Microsoft Windows) uses memory mapping (mmap) to load executables and dynamic libraries.

The contents of an executable or dynamic library are mmap’d into the linear address space of relevant processes. Therefore, any change in the underlying file affects the mmap’d memory regions and can potentially break programs. (MAP_PRIVATE guarantees changes by processes to those memory regions are handled by COW without affecting the underlying file. On the contrary, POSIX leaves to implementations whether COW should be used if the underlying file is modified. In fact, for purpose of efficiency, in Linux, such modifications are visible to processes even though MAP_PRIVATE may have be used.)

There is an option MAP_DENWRITE which disallows any modification to the underlying file, designed to avoid situations described above. Executables and dynamic libraries are all mmap’d with this option. Unfortunately, it turned out MAP_DENYWRITE became a source of DoS attacks, forcing Linux to ignore this option in recent versions.

Executables are mmap’d by the kernel (in the execve syscall). For kernel codes, MAP_DENYWRITE still works, and therefore we get “text busy” errors if we attempt to modify the executable.

On the other hand, dynamic libraries are mmap’d by userspace codes (for example, by loaders like /lib/ld-linux.so). These codes still pass MAP_DENYWRITE to the kernel, but newer kernels silently ignores this option. The bad consequence is that you can break the whole system if you think you’re only upgrading the C runtime library.

Then, how does install solve this problem? Very simple – unlinking the file before writing the new one. Then the old file (no longer present in directory entries but still in disk until the last program referring to it exits) and the new file have different inodes. Programs started before the upgrading (continuing using the old file) and those after the upgrading (using the new version) will both be happy.

# [fwd]王齐 。《后科技年代－－操作系统的思考》

ARM在手持移动领域的领先并不意味着这个阵营的伟大，而是x86阵营打败了自己。念及这段即将别离的往事，心中所思所想的是6500万年前白垩纪 恐龙的灭绝。在处理器微架构领域，这个时代已经没有留出更多的空间去继续容纳着庞然大物。ARM可以化整为零，活得稍好些。从更长远的角度上看，x86与 ARM间没有赢家。x86与ARM之争对参与的双方依然重要，却偏离了这个时代的主战场。这个时代不再属于硅与处理器微架构，依托在处理器微架构之上的传 统操作系统也已是昨日黄花。

Windows和Surface的设计模式延续着软件帝国产品设计的定式，从Features上看，这些产品无所不有，也一无所有。这些 Feature的罗列没有改变微软的处境，却使得微软的所有产品进一步单一化，使得Office，Exchange，Windows间的耦合更加紧密，成 为事实上的单一产品。在我们所处的移动互联网时代，软件帝国正在逼着芸芸众生为他们这个单一产品做一道单选题，使用还是放弃。软件帝国的危机已迫在眉睫。

PC帝国之悲！不在于错过了移动互联网，不在于错过了手持终端，可能也不在于我们所察觉到的诸多问题。PC帝国从来没有错过这些机会。不是手持移动 互联时代打败了PC帝国，这个帝国从头到尾都是被自己打败的。当一个公司的前途掌握在给华尔街看的财务报表时，微软不再是微软，Intel不再是 Intel。世上多数公司，危机的种子早在成立的当天种下，在Funder们陆续离开这家公司时出现转折。比尔盖兹离开微软，格罗夫离开Intel时，微 软不是微软，Intel不是Intel了。PC帝国已经长得太大，大到了没有几个员工再把这里当做家。

PC帝国永远明白自己的问题，却不知如何解决。可以导致昔日洛阳纸贵的产品，弃之如敝屣。丢掉了，捡不回来了，再也没有必要捡回来了，开始全力以 赴。凝视PC帝国的努力，心如万马奔腾。并非这个帝国人才匮乏，事实恰好相反，很多人早已远望冰山，却无法改变这支巨舰，开足马力，奋而向前的方向。一个 曾经强大的国家，一个曾经强大的公司在即将退出历史舞台时，往往具备一个相同的特性，分明人才遍野却视若不见，君臣举手无措，视面而泣。君非亡国之君，臣 非亡国之臣，做实了亡国君臣。

# 指针数组与数组指针

int *p[10] 指针数组：指向指针的数组，数组的元素是指针
int (*p)[10] 数组指针：指向数组的指针，就是一个指针而已，只不过指向的内容比较特别

 int *p[10]; for(int i = 0; i < 10; ++i) { p[i] = new int; *p[i] = i; } for(int i = 0; i < 10; ++i) { std::cout << *p[i] << std::endl; delete[] p[i]; } int (*p2)[10]; int arr[2][10]; p2 = &arr[1]; for(int i = 0; i < 10; ++i) { (*p2)[i] = i; } for(int i = 0; i < 10; ++i) { std::cout << (*p2)[i] << std::endl; }