《Accelerated C++》 笔记摘录

1. A variable is an object that has a name. it is possible to have 
   objects that do not have names,but variable must have a name. the 
   limited lifetime of local variables is one reason that it is 
   important to distinguish between variables and objects 
2. std::cin >> name; 
   when we ask the library to read a string , it begins by discarding 
 whitespace characters (space, tab, backspace or the end of the 
   line) from input, then reads characters into name until it en 
   encounters another whitespace character or end-of-line 
3. we can determine what the + operator does by examining the types 
   of its operands. when an operator has different meanings for 
   operands of different types, we says that the operator is 
 overloaded. 
4. whenever we define a variable that contains the size of a 
   particular data structure, it is a good habit to use the type that 
   the library defines as being appropriate for that specific 
   purpose. (e.std::string::size_type , unsigned integral type that 
   can hold the size of any string) 
5. There are several ways in which trying to read from a stream can 
   be unsuccessful 
   * we might have reached the end of the input file(end-of-file). 
   * we might have encountered input that is incompatible with the 
     type of the variable that we are trying to read, such as might 
     happen if we try to read an int and find something that isn't a 
     number. 
   * the system might have detected a hardware failure on the input 
     device. 
6. if we define a nonconst reference---a reference that allows 
   writing, we can not make it refer to a const object or reference. 
   if the function paremeter is a const reference, we can call this 
   function on behalf of both const and nonconst object. 
   a reference parameter without a const usually signals an intent to 
   modify the object that is the function's argument. 
7. An lvalue is a value that denotes a nontemporary object. for 
   example, a variable is an lvalue, as is a reference, or the result 
   of calling a function that returns a reference. A expression that 
   genenates an arithmetic value, such as sum / count, is not an 
   lvalue, the result of calling a function that returns a local 
   variable is not an lvalue. 
8. A good rule of thumb is to avoid more than one side effect in a 
   single statement. 
9. A predicate is a function that yields a truth value, typically of 
   type bool. 
10. std::string spaces(greeting.size(), ' '); --> definition 
    string(maxlen + 1 - students[i].name.size(), ' '); --> expression 
 (operand);
    The expression constructs a nameless object of type string. this 
    expression is similar to the definition of spaces, but it omits 
    the name of the variable. this omission effectively turn the 
    definition into an expression 
    like the: new classname(para1, pare2, …) --→ operator operand 
11. we can optionally qualify a function definition with inline, the 
    compiler needs to be able to see the function definition, so 
    inlines are usually defined in header files, rather than in 
    source files.
12. Vector, which is optimized for fast random access. One price of 
    that optimization is that is can be expensive to insert or delete 
    elements other than at the end of the vector.
13. if we know that our program uses only those operations that a 
    particular type of container supports efficiently, then we can 
    make our program more efficient by using that kind of container.
14. An iterator is a value that
    * Identifies a container and an element in the container
    * Lets us examine the value stored in that element
   * Provides operations for moving between elements in the container
    * Restrict the available operations in ways that correspond to 
      what the container can handle efficiently
15. by calling the dereference operator, *.when applied to an 
    iterator, the * operator returns an lvalue that is the element to 
    which the iterator refers.
16. if students were a container that did not support random-access 
    indexing, it is likely that students.begin() would be of a type 
    that did not have + defined.
17. in fact, calling erase on a vector invalidates all iterators that
    refer to elements after the one that just erased.Fortunately, 
    erase returns an iterator that is positioned on the element that 
    follows the one that we just erased.
18. Just as vectors are optimized for fast random-access, lists are 
    optimized for fast insertion and deletion anywhere within the 
    container. Like a vector, a list is a container that can hold 
    objects of most any type. As we'll see, lists and vectors share 
    many operations, One key operation that vectors support, but 
    lists do not,is indexing
19. For lists, the erase and pushback operations do not invalidate 
 iterators to other elements(while vectors will). Only iterators 
 that refer to the element actually erased are invalidated, 
 because that element no longer exists.
20. if we need to use this type more than once, we start by defining
 a shorter synonym for this type use typedef.
21. A generic algorithm is an algorithm that is not part of any 
 particular kind of container, but instead takes a cue from its 
 arguments' types about how to access data it uses. like copy(). 
22. iterator adaptors, which are functions that yields iterators 
 with properties that are related to their arguments in useful 
 ways. Like backinserter().
23. although the string type does not support all of the container 
 operations, it does support iterators and indexing.
24. It's not easy to pass an overloaded function directly as an 
 argument to a template function. The trouble is that the compiler 
 doesn't know which version of the overloaded function we mean, 
 because we haven't supplied any argument that compiler might use 
 to select a version.
25. if a container supports indexing, so do its iterators.
26. Algorithm act on container elements–they do not act on containers
 if the function like erase change the size of container, the 
 function must be a member of container, because it acts directly 
 on the container, not just on its elements.
27.In the case of vectors and strings, operations such as erase or 
 insert also invalidate any iterator denoting elements after the 
 one erased or inserted.Because these operations can invalidate 
 iterators, we must be careful about saving iterator values if we 
 are using these operations.Similarly, function such as partition 
 or remove_if, which can move elements around within the container, 
 will change which element is denoted by particular iterators.After 
 running one of these functions, we cannot rely on an iterator 
 continuing to denote a specific element.
28. because associative container are self-ordering, our own program 
 must not do anything that changes the order of the elements. For 
 that reason, algorithms that change the contents of containers 
 often don't work for associative container.
29. Each element in a map is really a pair, with a first member that 
 contains the key and a second member that contains the 
 associatived value.
30. There is no built-in concatencation operation for vectors.
31. When you try to index a map with nonexistent key, it 
 automatically creates an element with that key. because using 
 [](indexes the map using a key) to access a map might create a 
 new element,so [] isn't defined on a const map.
32. Such a function that we do not know what function's argument or 
 result type will be until we use it is called a generic function. 
 The language feature that implements generic function is called 
 template function. The template parameter types are inferred from 
 the argument types.
33. Each iterator category(five) correspond to a strategy for 
 accessing container elements. Thus, the iterator category give us 
 a way to understand which containers can use which algorithms.
34. It is worth noting that the “write-once” property is a 
 requirement on programs that use iterators ,not on iterators 
 themselves.
35. generic function : the part that is inside the language is the 
 idea that the ways in which a function uses a parameter of 
 unknown type constrain that parameter's type.the part that is 
 outside the language is the way in which the standard library 
 organizes the constraints on its function's parameters.
36. The vector and string iterators are random-access iterators.(the 
 sort function use this), however, the list iterator is not, it 
 support only bidirectional iterators. So the only way to navigate 
 through a list is to look at each element in sequence.
37. when we say that find function requires input iterators as its 
 argument, we are saying that we can give find argument of any 
 type that meets the input-iterator requirements, including 
 iterators that support additional operations.
38. template < class T > T zero() { return 0;}
 defines zero to be a template function with single type parameter 
 , which is used to name the return type. In calling this 
 function, we must supply the return type explicitly. double x = 
 zero<double> ();
39. code that is intended for use by others should contain the 
 minimal number of declarations necessary.
40. There is no way to call the size function from class string 
 without nominating a string object.
41. Putting :: in front of a name insists on using a version of that 
 name that is not a member of anything.
42. Member function that are const may not change the internal state 
 of the object on which they are excuting.
43. As always, argument types must be identical between the function 
 declaration and definition.
44. constructors are special member functions that define how objects 
 are initialized.There is no way to call a constructor explicitly.
 Instead, creating an object of class type calls the appropriate 
 constructor automatically as a side effect. The constructor that 
 takes no arguments is known as the default constructor.
45. When we create a new class object, sequence steps happen:
 (1)The implements allocates memory to hold the object(stack/heap)
 (2)It initializes the object using initial values as specified
 in the initializer list.
 (3)It executes the constructor body.
 The constructor initializers initializes all data members(the
 other members are initializerd implicitly by corresponding 
 type's default constructor)even if the initializer list does not 
 mention the members at all.
46. One way to determine the right interface is to look at the kind 
 of programs we want our users to be able to write.
47. The explicit keyword makes sense only in the definition of a 
 constructor that takes a single argument. When we say that a 
 constructor is explicit, we're saying that the compiler will use 
 the constructor only in contexts in which the user expressly 
 invokes the constructor, and not otherwise.
 Vec<int> vi(100); //ok,explicit construct the Vec from an int
 Vec<int> vi = 100; //error:implicitly construct the Vec and copy 
 it to vi.
48. If the operator is defined as a member function, then its left 
 operand(if it is a binary operator)or its only operand(if it is
 a unary operator)is implicitly bound to the object on which the 
 operator is invoked.
49. The this keyword is valid only inside a member function, where it 
 denotes a pointer to the object on which the member function is 
 operating.For a binary operator, such as assigment, this is bound 
 to the left-hand operand.
50. It is important to note that if a class defines any constructor
 explicitly, even a copy constructor, then the compiler will not 
 synthesize a default constructor for that class. If the class 
 author does not specify these operations, the compiler synthesizes 
 default versions of the unspecified operations to operate 
 recursively---copying, assigning, or destroying each data element 
 according to the appropriate rules for the type of that 
 element(class or built-in)
51. Remember that objects may be created, copied or destroyed 
 implicitly.Whether implicitly or explicitly, the compiler will 
 involve the appropriate operation.
52. The new operator both allocates and initializes memory, when 
 used to allocate an array of type T, it needs the default 
 constructor for T; when used to allocate a object of type T with
 arguments, it needs the appropriate constructor for T. 
53. The <memory> header provides a class, called allocator<T>, that 
 allocates a block of uninitialized memory that is intended to 
 contain objects of type T, and return a pointer to the initial
 element of that memory.
54. constructors are involved as a side effect of creating or copying
 objects; the assignment operator is involved in expressions 
 involving assignment; and the destructor is run automatically 
 when objects are destroyed or go out of scope.
55. In general,a class that needs no destructor(the class itself does
 no memory allocation may be)doesn't need an explicit copy 
 constructor or assignment operator either.(rule of three)
56. To control how every object of class T deals with its resourses,
 you need
 T::T() one or more constructors, perhaps with arguments
 T::~T() the destructor
 T::T(const T &) the copy constructor
 T & T::operator=(const T &) the assignment operator
57. we suggested that one way to decide whether one function should 
 be a member of class was to ask whether the operation affects the 
 state of the object.But like the input operator certainly changes 
 its'object's state, however,we don't make it a member function.
58. A friend has the same access rights as a member. Classed can also
 be named friends.
59. like the assignment operator itself, all of the compound 
 assignment operators(like +=, -=, *=, /=)should be members 
 of class,then that the operator's left operand cannot be 
 the result of an automatic conversion(a temporary object).
60. In general, it is useful to make explicit the constructors that
 define the structure of the object being constructed, rather than
 its contents. Those constructors whose arguments become part of 
 the object usually should not be explicit.The compiler will not 
 use an explicit constructor to create objects implicitly by 
 converting operands in expression or function calls.
61. A class can define conversion in two ways: It can convert from
 other types to its type, or from its type to other types.
 User-defined conversions say how to transform to and from objects 
 of class type. some nonexplicit constructors may be 
 acts as a user-defined conversion.
62. Conversion operators must be defined as a member of a class,like
 class student_info {
 public:
 operator double() const;
 };
 would say how to create a double from a student_info object.the
 meaning of this conversion would depend on the definition of the
 operator
63. Conversion operators are most often useful converting from a 
 class type to a built-in type, but they can also be useful when
 converting to another class type for which we do not own the code
 if two classes define conversions to each other's types, 
 ambiguities can result.
64. The standard library defines a conversion from type istream to 
 void *(it's a pointer that can point to any type of object)(the
 class istream define operator void*),using a value of any
 arithmetic or pointer type automatically converts the value to 
 type bool.so we can write if (cin >> x) {}
65. Derived objects are constructed by
 * Allocating space for the entire object(base-class members as 
 well as derived members)
 * Calling the base-class constructor to initializer the 
 base-class parts of the object.(two steps)
 * Initializing the members of the derived class as directed by 
 the constructor initializer
 * Executing the body of the derived-class constructor, if any.
66. The virtual keyword may be used only inside the class definition. 
 it will determine which function to run at run time by
 inspecting each object that we pass an argument to function.
67. The phrase dynamic binding captures the notion that functions may
 be bound at run time(through a reference or pointer), as opposed 
 to static binding that happen at compile time(through a object). 
68. C++ supports polymorphism through the dynamic binding properties
 of virtual function.
69. The virtual functions must be defined, regardless of whether the
 program calls them .Nonvirtual functions may be declared but not
 defined, as long as the program does not call them.
70. The synthesized destructor will run the destructor for each data 
 element in the class.
71. a static member function is associated with class, not with a 
 particular object. As such, they cannot access the nonstatic data
 members of objects of the class.Their names are within the scope
 of their class.
72. Ordinarily, when a derived class redefines a function from the 
 base class, it does so exactly:the parameter list and the return
 type are identical.However, if the base-class function returns a 
 pointer(or reference)to a base class, then the derived-class 
 function can return a pointer(or reference) to a corresponding 
 derived class.
73. It is important to realize that when a base- and derived-class 
 function have the same name, but they don't match exactly in 
 number and types of parameters ,they behave as if they were
 completely unrelated functions.
74. If a pointer to the base class is used to delete an object that
 might actually be a derived-class object, then the base class
 needs a virtual destructor. It's inherited by the derived classes
 and there is no need to redefine the destructor in the derived 
 classes.
75. calls to virtual function from inside a constructor are 
 statically bound to the version for the type being constructed.
76. Using pointers leading to pitfalls:
 *Copying a pointer does not copy the corresponding object,leading
 to surprises if two pointers inadvertently point to the 
 same object.
 *Destroying a pointer does not destroy its object, leading to
 memory leak.
 *Deleting an object without destroying a pointer to it leads to a 
 dangling pointer, which also causes undefined behaviour if the 
 program uses the pointer.
 *Creating a pointer without initializing it leaves the pointer 
 unbound, which also causes undefined behaviour if the 
 program use it.
77. template<> at the beginning of the function indicates that the 
 function is a template specialization. Such specializations 
 defines a particular version of a template function for the
 specific argument type.
78. Remember that conversions are not applied to the left operand of 
 the . Operator 
79. The way that we specify that we don't intend to implement a 
 virtual function is to say = 0. Doing so makes it a pure virtual
 function. By giving a class even a single pure virtual function,
 we are also implicitly specifying that there will never be 
 objects of that class. Such classes are called abstract base 
 classes, because they exist only to capture an abstract interface
 for an inheritance hierarchy. They are purely abstract: There are 
 no objects of that base class itself. Once we give a class any 
 pure virtuals, the compiler will enforce our design by preventing 
 us from creating any objects of an abstract class.
80. As with virtual itself, the fact that a function is pure virtual
 is inherited. If a derived class defines all of its inherited 
 pure virtual functions. It becomes a concrete class, and we can 
 create objects of that class.
81. It is important to realize that abstract classes may define data
 members, and(ordinary)member functions, as well as static ones. 
 These functions will access the base-class objects that are part 
 of derived objects.
82. Static members(both functions and data members)are useful in that
 they let us minimize the names that are defined globally.
83. A member of a derived class can access the protected members of 
 the base-class parts of objects of its own class, or of other
 classes derived from it, but it cannot access the protected 
 members of base-class objects that stand alone----that is , that
 are not part of a derived-class object.

注:从本人笔记直接粘贴,排版不是很好,大家将就着看看.


 

你可能感兴趣的:(C++,Accelerated)