C ++ primer 笔记

来源:互联网 发布:jdbc mysql 编辑:程序博客网 时间:2024/06/07 06:20

chapter 1

The library defines four IO objects. To handle input, we use an object of type istreamnamedcin (pronounced see-in). This object is also referred to as the standard input. For output, we use anostreamobject namedcout (pronounced see-out). This object is also known as thestandard output. The library also defines two otherostreamobjects, namedcerrand clog(pronounced see-err and see-log, respectively). We typically usecerr, referred to as thestandard error, for warning and error messages andclogfor general information about the execution of the program.

The <<operator takes two operands: The left-hand operand must be anostream object; the right-hand operand is a value to print. The operator writes the given value on the givenostream. The result of the output operator is its left-hand operand. That is, the result is theostreamon which we wrote the given value. 


The second operator prints endl, which is a special value called amanipulator.Writingendlhas the effect of ending the current line and flushing thebuffer associated with that device. Flushing the buffer ensures that all the output the program has generated so far is actually written to the output stream, rather than sitting in memory waiting to be written.
Programmers often add print statements during debugging. Such statements should always flush the stream. Otherwise, if the program crashes, output may be left in the buffer, leading to incorrect inferences about where the program crashed.


chapter 2

void* Pointers. The type void*is a special pointer type that can hold the address of any object. Like any other pointer, avoid*pointer holds an address, but the type of the object at that address is unknown:

double obj = 3.14, *pd = &obj;// ok: void* can hold the address value of any data pointer typevoid *pv = &obj; //obj can be an object of any typepv = pd; // pv can hold a pointer to any type
There are only a limited number of things we can do with avoid*pointer: We can compare it to another pointer, we can pass it to or return it from a function, and we
can assign it to another
void* pointer. We cannot use avoid*to operate on the object it addresses—we don’t know that object’s type, and the type determines what operations we can perform on the object. Generally, we use avoid*pointer to deal with memory as memory, rather than using the pointer to access the object stored in that memory. 

References to Pointers. Because a pointer is an object, we can define a reference to a pointer:

int i = 42;int *p; // p is a pointer to intint *&r = p; //r is a reference to the pointer pr = &i; // r refers to a pointer; assigning &i to r makes p point to i*r = 0; // dereferencing r yields i,the object to which p points; changes i to 0
The easiest way to understand the type ofris to read the definition right to left. The symbol closest to the name of the variable (in this case the&in &r) is the one that
has the most immediate effect on the variable’s type. Thus, we know that
ris a reference. The rest of the declarator determines the type to whichrrefers. The next
symbol,
* in this case, says that the typerrefers to is a pointer type. Finally, the base type of the declaration says thatris a reference to a pointer to anint.

A referencedefines an alternative name for an object. A reference type “refers to” another type. We define a reference type by writing a declarator of the form&d, where d is the name being declared:

int ival = 1024;int &refVal = ival; // refVal refers to (is another name for) ivalint &refVal2; // error: a reference must be initialized

When we define a reference, instead of copying the initializer’s value, webind the reference to its initializer. Once initialized, a reference remains bound to its initial object. There is no way to rebind a reference to refer to a different object. Because there is no way to rebind a reference, references must be initialized. 

A reference is not an object, so we cannot make a reference itselfconst.Indeed, because there is no way to make a reference refer to a different object, in some sense all references areconst. Whether a reference refers to aconstor nonconst type affects what we can do with that reference, not whether we can alter the binding of the reference itself.


It is important to realize that are ference toconst restricts only what we can do through that reference. Binding a reference to constto an object says nothing about whether the underlying object itself is const. Because the underlying object might be non const, it might be changed by other means. 

const int a = 1;
int &b = a;//error the non-const referrence int &b can't bind a referrence to a const object ,
int p = -1, &r = 0;//error the non-const referrence int &r can't bind a referrence to  a const object ,because the "0" is most likely a const intconst int i = 0, &j = 0;//ok


If there is no object to bind to a pointer, then initialize the pointer tonullptr orzero. That way, the program can detect that the pointer does not point to an object.

We store the address of a const object only in apointer to const:

const double pi = 3.14; //pi is const; its value may not be changeddouble *ptr = π //error: ptr is a plain pointerconst double *cptr = π //ok: cptr may point to a double that is const*cptr = 42; //error: cannot assign to *cptr 
there are two exceptions to the rule that the types of a pointer and the object to which it points must match. The first exception is that we can use a pointer to const to point to a non const object:
double dval = 3.14; //dval is a double; its value can be changedcptr = &dval; //ok: but can't change dval through cptr
Like a reference toconst, a pointer to constsays nothing about whether the object to which the pointer points is const. Defining a pointer as a pointer toconst affects only what we can do with the pointer. It is important to remember that there is no guarantee that an object pointed to by a pointer toconstwon’t change.

const Pointers. Unlike references, pointers are objects. Hence, as with any other object type, we can have a pointer that is itself const. Like any other const object, aconst point must be initialized, and once initialized, its value (i.e., the address that it holds) may not be changed. We indicate that the pointer is constby putting the constafter the

*. This placement indicates that it is the pointer, not the pointed-to type, that is const:

int errNumb = 0;int *const curErr = &errNumb; //curErr will always point to errNumbconst double pi = 3.14159;const double *const pip = π // pip is a const pointer to a const object
The fact that a pointer is itselfconst says nothing about whether we can use the pointer to change the underlying object. Whether we can change that object depends entirely on the type to which the pointer points. 

By Default, const Objects Are Local to a File When aconst object is initialized from a compile-time constant, such as in our definition ofbufSize:
const int bufSize = 512; // input buffer size
the compiler will usually replace uses of the variable with its corresponding value during compilation. That is, the compiler will generate code using the value512 in the places that our code usesbufSize. 
To share aconst object among multiple files, you must define the variable asextern.

// file_1.cc defines and initializes a const that is accessible to other filesextern const int bufSize = fcn();// file_1.hextern const int bufSize; // same bufSize as defined in file_1.c
In this program,file_1.cc defines and initializesbufSize. Because this declaration includes an initializer, it is (as usual) a definition. However, becausebufSize is

const, we must specifyextern in order forbufSize to be used in other files. The declaration infile_1.h is also extern. In this case, theextern signifies thatbufSize is not local to this file and that its definition will occur elsewhere.


something about top-level const and low-level const, it's awful to me to fix on it. But blow example can easy explain it:

int i = -1;const int *m = &i;//ok, we could convert int* to const int *const int &n = i;//ok, we could bind const int& reference to ordinary intconst int j = -1;int *s = &j;//error: j has a low-level const, but s is doesn't,int &t = j;//error: can't bind ordinary int& to a const int object



A constant expression(the type of constexpre include in <array>, but many IDE doesn't support the  ISO C++ 2011 standard,such as vs and codeblocks :-()is an expression whose value cannot change and that can be evaluated at compile time. A literal is a constant expression. Aconst object that is initialized from a constant expression is also a constant expression.  

const int max_files = 20; // max_files is a constant expressionconst int limit = max_files + 1; // limit is a constant expressionint staff_size = 27; // staff_size is not a constant expressionconst int sz = get_size(); // sz is not a constant expression
Although staff_sizeis initialized from a literal, it is not a constant expression because it is a plainint, not a const int. On the other hand, even thoughsz is a const, the value of its initializer is not known until run time. Hence,sz is not a constant expression. 

Under the new standard, we can ask the compiler to verify that a variable is a constant expression by declaring the variable in aconstexpr declaration. Variables declared asconstexpr are implicitlyconst and must be initialized by constant expressions:

constexpr int mf = 20; // 20 is a constant expressionconstexpr int limit = mf + 1; // mf + 1 is a constant expressionconstexpr int sz = size(); // ok only if size is a constexpr function
Because a constant expression is one that can be evaluated at compile time, there are limits on the types that we can use in aconstexpr declaration. The types we can use in aconstexpr are known as “literal types” because they are simple enough to have literal values. Of the types we have used so far, the arithmetic, reference, and pointer types are literal types. OurSales_item class and the library IO andstring types are not literal types.Although we can define both pointers and reference as constexprs, the objects we use to initialize them are strictly limited. We can initialize aconstexpr pointer from thenullptr literal or the literal0. We can also point to (or bind to) an object that remains at a fixed address.variables defined inside a function ordinarily are not stored at a fixed address. Hence, we cannot use aconstexpr pointer to point to such variables. On the other hand, the address of an object defined outside of any function is a constant expression, and so may be used to initialize a constexprpointer.  functions may define variables that exist across calls to that function. Like an object defined outside any function, these special local objects also have fixed addresses. Therefore, a constexpr
reference may be bound to, and a constexprpointer may address, such variables. 

The difference between const and constexpr is: const can be initialized in compile time or run time, but constexpr is restricted only can be evaluated in compile time.
The usage of pointers and constexpr:

const int *p = nullptr; // p is a pointer to a const intconstexpr int *q = nullptr; // q is a const pointer to int


the type auto(defined in the  ISO C++ 2011 standard, sucks).It is not uncommon to want to store the value of an expression in a variable. To declare the variable, we have to know the type of that expression. Under the new standard, we can let the compiler figure out the type for us by using the auto type specifier. autotells the compiler to deduce the type from the initializer. By implication, a variable that usesauto as its type specifier must have an initializer:
// the type of item is deduced from the type of the result of adding val1 and val2auto item = val1 + val2; // item initialized to the result of val1 + val
Here the compiler will deduce the type ofitem from the type returned by applyingto val1and val2. Ifval1 and val2are Sales_item objects, item
will have type Sales_item. If those variables are typedouble, then item has type double, and so on.
As with any other type specifier, we can define multiple variables using
auto.Because a declaration can involve only a single base type, the initializers for all the variables in the declaration must have types that are consistent with each other:
auto i = 0, *p = &i; // ok: i is int and p is a pointer to intauto sz = 0, pi = 3.14; // error: inconsistent types for sz and pi 



chapter 3

using namespace::name; 

Code inside headers ordinarily should not useusing declarations.The reason is that the contents of a header are copied into the including program’s text. If a header has ausing declaration, then every program that includes that header gets that sameusing declaration. As a result, a program that didn’t intend to use the specified library name might encounter unexpected name conflicts. 


Library string type.Table below lists the most common ways to initializestrings. Some examples:

string s1; // default initialization; s1 is the empty stringstring s2 = s1; // s2 is a copy of s1string s3 = "hiya"; // s3 is a copy of the string literalstring s4(10, 'c'); // s4 is cccccccccc 






















0 0
原创粉丝点击