|  | 
| 1 |  | -# read_cpp_primer | 
|  | 1 | +# CPP Primer Note | 
|  | 2 | + | 
|  | 3 | +This README contains important/hard points while reading the book.  | 
|  | 4 | + | 
|  | 5 | +## Reference in C++  | 
|  | 6 | + | 
|  | 7 | +### 1. No rebinding | 
|  | 8 | +#### From the book:  | 
|  | 9 | +> A reference defines an alternative name for an object.  | 
|  | 10 | + | 
|  | 11 | +> When we define a reference, instead of copying the initializer's value, we **bind** the reference to ins initializer. There is no way to rebind a reference to refer to a different object. Thus, references **must** be initialized.  | 
|  | 12 | + | 
|  | 13 | +#### From Tensorflow:  | 
|  | 14 | + | 
|  | 15 | +https://stackoverflow.com/a/728272 | 
|  | 16 | +> The reason that C++ does not allow you to rebind references is given in Stroustrup's "Design and Evolution of C++" : | 
|  | 17 | +>> It is not possible to change what a reference refers to after initialization. That is, once a C++ reference is initialized it cannot be made to refer to a different object later; it cannot be re-bound. I had in the past been bitten by Algol68 references where r1=r2 can either assign through r1 to the object referred to or assign a new reference value to r1 (re-binding r1) depending on the type of r2. I wanted to avoid such problems in C++.  | 
|  | 18 | +
 | 
|  | 19 | + | 
|  | 20 | +https://stackoverflow.com/a/728249 | 
|  | 21 | +> In C++, it is often said that "the reference is the object". In one sense, it is true: though references are handled as pointers when the source code is compiled, **the reference is intended to signify an object that is not copied when a function is called.** Since references are not directly addressable (for example, references have no address, & returns the address of the object), it would not semantically make sense to reassign them. Moreover, C++ already has pointers, which handles the semantics of re-setting.  | 
|  | 22 | + | 
|  | 23 | +### 2. Reference is not an object  | 
|  | 24 | +#### From the book | 
|  | 25 | +> A reference is not an object. Instead, a reference is just another name for an already existing object.  | 
|  | 26 | + | 
|  | 27 | +> When we assign to a reference, we are assigning to the object bound with the reference.  | 
|  | 28 | +> When we fetch the value of a reference, we are really fetching the value of the object bound with the reference.  | 
|  | 29 | +> Similarly, when we use a reference as an initializer, we are really using the object bound with the reference.  | 
|  | 30 | + | 
|  | 31 | +https://stackoverflow.com/a/728299  | 
|  | 32 | +> A reference is not a pointer, it may be implemented as a pointer in the background, but its core concept is not equivalent to a pointer. A reference should be looked at like it **IS** the object it is referring to.  | 
|  | 33 | +> A pointer is simply a variable that holds a memory address. **The pointer itself has a memory address of its own, and inside that memory address it holds another memory address that it is said to point to.** A reference is not the same, **it does not have an address of its own**, and hence it cannot be changed to "hold" another address.  | 
|  | 34 | +>> The reference itself isn't an object (it has no identity; taking the address of a reference gives you the address of the referent; remember: the reference is its referent). | 
|  | 35 | +
 | 
|  | 36 | + | 
|  | 37 | +### 3. Reference type  | 
|  | 38 | +With two exceptions, the type of a reference and the object it binds with must match exactly. Moreover, a reference may be bound only to an object, not to a literal.  | 
|  | 39 | + | 
|  | 40 | +Two exceptions:  | 
|  | 41 | +1. We can initialize [ a reference to `const` ] from any expression that can be converted to the type of the reference. We can bind a reference to `const` to a non-`const` object or literal.  | 
|  | 42 | + ```C++ | 
|  | 43 | + int i = 10; | 
|  | 44 | + const int &r1 = i; // bound with non constant int object | 
|  | 45 | + const int &r2 = 10; // bound with int literal | 
|  | 46 | + ``` | 
|  | 47 | + Reason:  | 
|  | 48 | + When binding to an object of a different type, a temporary object is created by the compiler. I.e,:  | 
|  | 49 | + ```C++ | 
|  | 50 | + double d = 1.0; | 
|  | 51 | + const int &ri = d; | 
|  | 52 | + ```  | 
|  | 53 | + becomes:  | 
|  | 54 | + ```C++ | 
|  | 55 | + double d = 1.0; | 
|  | 56 | + const int temp = d; | 
|  | 57 | + const int &ri = temp; | 
|  | 58 | + ```  | 
|  | 59 | + In this case, the reference is bound to a **temporary** object. If `ri` is not constant, we can assign to `ri`, which is essentially assigning to the temporary object. However, the programmer would probably expect that assigning to `ri` would change `d`, as no one would want to change the value of a temporary object. So, C++ makes this illegal.  | 
|  | 60 | + | 
|  | 61 | +2. Covered much later.  | 
|  | 62 | + | 
|  | 63 | + | 
|  | 64 | + | 
|  | 65 | +## Default Initialization  | 
|  | 66 | +- For built-in type(int, double, char, etc.), initializaed to `0` if not defined within any function, otherwise initialized to `undefined`.  | 
|  | 67 | +- For non built-in type, initialized according to the class definition.  | 
|  | 68 | + | 
|  | 69 | +## Arrays and Pointers  | 
|  | 70 | +> In C++ pointesr and arrays are closely intertwined. In particular, when we use an array, the compiler ordinarily converts the array to an pointer. ... **in most places** when we use an array, the compiler automatically substitutes a pointer.  | 
|  | 71 | + | 
|  | 72 | +Examples:  | 
|  | 73 | +1. When using `auto` | 
|  | 74 | + ```C++ | 
|  | 75 | + int arr[] = {0, 1, 2}; | 
|  | 76 | + auto ip(arr); // arr is an int * pointing to the first element | 
|  | 77 | + ``` | 
|  | 78 | + | 
|  | 79 | +2. When using subscipt  | 
|  | 80 | + ```C++ | 
|  | 81 | + int arr[] = {0, 1, 2}; | 
|  | 82 | + int i = arr[2]; // arr is converted to be a pointer | 
|  | 83 | + // equivalent to: int i = *(arr + 2) | 
|  | 84 | + ```  | 
|  | 85 | + | 
|  | 86 | +3. Multi-dimensional array Range `for`  | 
|  | 87 | + ```C++ | 
|  | 88 | + constexpr size_t rowCount = 3, colCount = 4; | 
|  | 89 | + int arr[rowCount][colCount]; | 
|  | 90 | + | 
|  | 91 | + size_t count = 0; | 
|  | 92 | + for (auto &row : arr){ | 
|  | 93 | +  for (auto &col: row){ | 
|  | 94 | +  col = count; | 
|  | 95 | +  count++; | 
|  | 96 | +  } | 
|  | 97 | + } | 
|  | 98 | + | 
|  | 99 | + for (auto &row : arr){ // & is required even for reading (*) | 
|  | 100 | +  for (auto col: row){ | 
|  | 101 | +  cout << col << endl; | 
|  | 102 | +  } | 
|  | 103 | + } | 
|  | 104 | + ``` | 
|  | 105 | + The `&` is required to avoid the normal array to pointer conversion by the compiler. If `&` is neglected, `row` would be converted to a pointer pointing to the first element of the 4-element array, `row` has type `int *`. Then the inner loop is illegal.  | 
|  | 106 | + | 
|  | 107 | + | 
|  | 108 | + | 
|  | 109 | + | 
|  | 110 | + | 
|  | 111 | + | 
|  | 112 | + | 
|  | 113 | + | 
0 commit comments