As a former C programmer (as a student), this seems to be a familiar topic to me : really, the only thing you need to learn about C is pointers. However, people like me need to be aware of certain things.
void *. The book mentions that void * must be explicitly converted before it is assigned to a certain pointer type. I can’t remember that if you can use it without
String literal are used to initialize const char * or a char array. If we assign it to char *, it must be a const. It is understandable since it should be put in the “.rodata” part when we don’t have an array in memory to store it. (This is implementation defined but putting in .rodata is reasonable. For the same reason, same const char * to the “same” string literal may or may not equals to each other.) Like python, C++ now also provides prefix R, and other prefixes for different character sets.
Arrays are pretty low level. According to the author, unless we need a simple fixed-length sequence of objects of a given type in memory, we should avoid using it. We have
Arrays are a tricky thing by definition in C. Unlike other modern programming languages, it is just multiple pieces of memory adjacent to each other. It doesn’t provide any high-level management, and array variables are implicitly converted to pointer immediately when you try to use it, in a function call or not. [] is no more than a symmetric sugar when not using it in a definition. However, without a parameter passing, an array name is not a pointer, therefore the range-for works on it!
Note that random accesses should not be more expensive than an iterator, according to the book.
Arrays are implicitly converted to pointers when used as an interface. However, this only works for one dimension. For multidimensional arrays, all dimensions except the first one must be known and hard coded. Otherwise, we have to pass a simple pointer and deal with the index ourselves. A pointer to pointer won’t work since this is a pointer to an array.
Const pointer or pointer to const value is different in nature. We can tell from them by looking at what is before the keyword const
.
Reference is introduced in C++ and not in C. If you think about it, it is like syntactic sugar (of pointer) at some point. However, it has some benefit. User cannot change the address it points to, and there is no null reference. References are not objects, but they must be initialized during declaration. There is no array of references.
There are three kinds of references: lvalue reference, rvalue reference, and const reference. Const reference is not necessarily initialized by an lvalue. const doube& cdr {1}
is acceptable. We need to kind in mind of the scope for the tempory value. But in the real use case of const reference, where const is added in the parameter, this is not a problem.
There are two additional tips for lvalue reference. First, when we modify a reference argument in a function, we better hint the reader we’ll do things like this. Second, reference can also be the return value. Say, for operator [].
Rvalue reference is not syntactic sugar for sure. According to the book, “rvalue reference refers to a temporary object, which the user of the reference can (and typical will) modify, assuming that the object is never be used again.” std::move
seems to be a typical use of this. Because of this, we can only bind rvalue reference to temporary values, like string&& rr1{f()}
or string&& rr2{"String"}
.
I have to admit that it is the “ah-hah” time for me when I read the part move(x)
is just static_cast<X &&> x
. It doesn’t really move x, so the author thinks it would have been better is just called by rval
.
Reference of reference is still a reference. Lvalue reference unless it is rvalue reference of rvalue reference.
Pros and Cons have been enumerated, but I still have one thing missed: we can overload operators on references, but not pointers. Operators on pointers cannot be overloaded by pointers.