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.
注:从本人笔记直接粘贴,排版不是很好,大家将就着看看.