This is the traditional translation of "C frequently asked Questions" found from Taiwan http://www.cis.nctu.edu.tw/chinese/doc/research/, found "C Frequently Asked Questions" Ye Bingzhe, is also a translator of "C Programming Language" 3 / e, this article is very good, paying it for learning purposes, I didn't get the author's authorization, the copyright of the original article still belongs to the original author .c Language FAQ === PART 2/4 ===================================== Comp.lang.c Frequently Asked Questions List (with Answers , Fortunately) .copyright (c) 1991-96 Marshall P. Cline, ph.d.posting 2 of 4.posting # 1 Explains Copying Permissions, (NO) Warranty, Table-of-Contents, etc ====== ======================= ■ □ Section 9: Free Memory Management =================== =========== Q33: "DELETE P" will delete the "P" pointer or what it refers to the information, "* p"? The information indicated by the pointer. "Delete" actually means: "Delete the Thing Pointedto BY). The same English misuse also happens in the "release" pointer points to the "release" pointer "(" free (p) "true meaning:" free_the_stuff_pointed_to_by (p) ").
================================================= q34: I can "free ()" Is it configured by "new", "DELETE" is configured by "Malloc ()"? Not. In the same program, using Malloc / Free and New / Delete is completely legal, reasonable, secure; however, FREE is configured by New, or delete is not legal, unreasonable, It was awkward. ================================================================== in "new" rather than Old-fashioned malloc ()? Constructing sub / decimalizes, type security, OverridAbility. Construct Sub / Deconstructure: and "Malloc (SIZEOF (FRED)" "" New Fred () "also calls Fred's constructors. Similarly, "Delete P" will call "* p" deconstruction. Typical security: malloc () will return a "VOID *" that does not have a fixed security, and "New Fred ()" will pass back the correct type pointer (a "fred *"). Override: "new" is a number of operations that can be covered by the object category, and "Malloc" is not a baseline that is covered by "various categories". ================================================= q36: Why is C not replaced "new" and "DELETE" with a "Realloc ()"? Avoid you cause accident. When Realloc () is to copy the configuration area, it is made of "bitbus bitwise" copy, which can make most of the C objects. However, C objects should be able to copy themselves: Use their own copy to construct a sub-or set the operand.
================================================ q37: How do I configure / release arrays? Use new [] and delete []: fred * p = new fred [100]; // ... delete [] p; whenever you use "[...]" in the "New" expression It is necessary to use "[]" in the "DELETE" statement. ^^^^ This syntax is necessary, because "pointing to a single element" and "pointer pointing to an array" is not distinguished in grammar. ===============================================112 What do you forget? ] "What happens in the array configured by" DELETE "by" New Fred [N] "? disaster. This is the programmer - instead of the compiler - responsibility to ensure the correct pairing of new [] and delete []. If you make a mistake, the compiler does not generate an error message for any compile period or execution period. Stacking (HEAP) is destroyed is the most likely ending, or worse, your program will be caught. ================================================================================================================================================================================================================================================================================================= q39: Is the action legal (and good)? As long as you are careful, there is fine. My so-called "careful" is: 1) You have to determine "this" is configured by "New" (not "new []", also non-policy "new" version, must be the most original "new"). 2) You have to get 100% to determine that the member function is the last one of this object. 3) After the action of suicide ("delete this;"), you can't touch the object of "this", including information and operational behavior. 4) After completing the action of suicide ("delete this;"), you can't touch "this" pointer. In other words, you can't view it, compare it with other pointers or NULL, and transform it, do anything to it. Naturally, this warning also applies to: When "this" is a pointer to the base category, the deconstruction is not a Virtual.
============================================================================================================================================================= Array? There are many ways to terminate your requirements for the scalability of the array size. Extreme little, if you know the dimension of all arrays in the compile period, you can configure (just like C): Class Fred {/*...*/}; void manipulateArray () {Fred Matrix [10 ] [20]; // Using Matrix [i] [j] ... // Does not necessarily release the array} Another extreme situation, if you want each small piece of the matrix, you It can be configured in free memory: Void ManipulateArray (unsigned nRows []) // 'nROWS' is the number of columns of the array. // So the legal column number is (0, nROWS-1) open section. // 'ncols [r]' is the number of rows of 'R' columns ('R' value fields [0..nrows-1]). {Fred ** matrix = new fred * [nROWS]; for (unsigned r = 0; r
For example, with the previous FAQ, if you only need the first dimension size to change, you can New an array (rather than array of array "): consT unsigned ncols = 100; // 'ncols' is not the variable decided by the execution period (used to represent the number of lines) Class Fred {...}; void manipulateArray (unsigned nrows) // 'nROWS' is the variable determined by the execution period. (Used to represent the number of columns of array) {FRED (* matrix) [ncols] = new fred [nROWS] [ncols]; // to process // deletion is the counterput of the object configuration: If you don't just want to change the first dimension of the array, you can't do this. ===================================================== how to ensure that some types of objects are Use "new", not zone or overall / static variable? Determining the category of this category is "private:", and define a "friend" or "static" function to pass a target to the object that is built by "new" (set the constructive "protected:", If you want to have a derivative category). Class Fred {// only allows Fred to dynamically configure public: static fred * create () {return new fred ();} static fred * create (INT i) {return new fred (i);} static fred * crete CONST FRED & FRED () {Return New Fred ();} private: Fred (); Fred (INT i); Fred (const fred & fred); Virtual ~ fred ();}; main () {fred * p = fred: : Create (5); ... delete p;} =============================== ■ Section 10: Include and error handling ======================================== q43: How to handle the built-in error? Throw an Exception. The construction of the subsection does not return value, so it is impossible to use the error code it returns. Therefore, the best way to detect the built-in error is to throw an exception.
Before the C compiler has not provided exception processing, we can first put objects in "Semipe" state (such as: setting an internal status bit), use a query sub ("Inspector" to check the bit, you can let The user checks if the object is still alive. You can also use another member function to check this bit. If the object is not survived, you can do a "no action" (or more like "Abort ()"). But this is really ugly. ==================================================================================================================================================================================================================== # How to deal with its resources? Each information in the object is a member of your own. If the constructon throws an exception, the deconstruction of the object will be "not". If your object has to reply some things have been done (like configuring memory, opening file, locking semaphore), the information within the object "must" remember this "must recover things". For example: do not put the configured memory into the "Fred *" data member, and put it in a "Smart Pointer" member; when the "smart pointer" is dead, it The deconstruction subsection will delete the Fred object. [Translation] "Smart Pointer" is mentioned in Q4. ============================= ■ □ Section 11: Const correctness ============ ================= Q45: What is "const corrence"? good question. "Constant correctness" is a "const" keyword to ensure that constant objects will not be fooled.
For example, if the "F ()" function receives a "string", "F ()" wants to make sure "string" will not be changed, you can: * Pass By Value: Void F (String S) {/ *...*/} * Transmitctory: Void F (const string & s) {/ *...*/} * Transmitten to a constant pointer: void f (const string * sptr ) {/ *...*/} *, but cannot use a very number reference: void f (string & s) {/ /} * can not use very numbers: Void F (String * SPTR) {/ In the function of receiving "const string &" parameters, if you want to get to "S", you will generate a compile time; there is no space and speed at any time of execution. The declaration "const" parameter is also another type of security method, just like a constant string, it will "lose" all kinds of behavior movements that may change their content. If you find the type of security nature to make your system correctly (this is true; especially large systems), you will find that "constant correctness" is also. ======================================================================================================================================= Is there a constant correctness? The more, the better, the better. Delaying constant correctness will result in snowball effect: Every time you use "const", you have to add more than four "const" in "there". ================================================ q47: What is "Const member function"? A member function that only detects (not more) its object. Class Fred {public: void f () const;}; // ^^^^^ - hint "fred.f ()" does not change to "fred" This means: "Abstract Hierarchy" ( User-visible) object status is not changed (not promised: "Every bit content" of this object is not passive). The C compiler will not promise you to "every bit" thing, because it is not a constant alias (alias) may modify the status of the object (stick the "const" pointer on an object, and cannot guarantee that the object is not Changed; it can only be guaranteed that the object will not be "changed by this pointer"). [Translation] Please read this sentence by word.
"Const" member function is often referred to as "INSPECTOR), not" Const "member function, called" Mutator ". ========================================================= q48: If I want to be members of "const" Update a member of the "invisible" information, what should I do? Use "mutable" or "const_cast". [Translation] This is a very new ANSI C RTTI (Runtime Type Information), BorlandC 4.0 is the first to provide const_cast operation. A small number of queries need to do some harmless changes to the information (such as: "set" object, you might want to get it to get the next time to accelerate the next query). This change is "harmless" means that this change will not be detected by the external interface of the object (otherwise, the operation behavior should be called more motion, not the query). In this case, the member being fidilized will be labeled as "mutable" ("mutable" keywords in front of the document member declared; that is, the same place as "const"), this Will tell the compiler: This data member allows the Const member function to change. If you can't use "mutable", you can use "const_cast" to transform "THIS" to the "constantity". For example, in "set :: lookup () const", you can say: set * self = const_cast
This situation is rare (when the object is established) when the object is enabled in the Const member function; when all non-constable member functions are enabled, and the enabled of the Const member function is static; The enabled is also "inline"; when the constructing subscribers are "inline"; and when any member functions of the campaign calls are inline). [Translation] This paragraph is hard to turn well (okay! I am less skill ...: - <), so attachment original: Even if a compiler outlawed "const_cast", The Only Way to Avoid FlushtingThe Register Cache across a "const" member function call would be toensure that there are no non-const pointers that alias the object. Thiscan only happen in rare cases (when the object is constructed in the scopeof the const member fn invocation, and when all the non -const memberfunction invocations between the object's construction and the constmember fn invocation are statically bound, and when every one of theseinvocations is also "inline" d, and when the constructor itself is "inline" d, and when any member fns the constructor calls are INLINE). ===================== ■ □ Section 12: Inheritance =================== == Q50: "Inherited" is very important to C ? Yes it is. "Inherited" is a large profile of Abstract Data Type (ADT) and OOP. ================================================= q51: When should I use inherit? As a mechanism for "Specialization). Humans abstracts things in two angles: "Part-of) and" Kind-of). Ford Auto "is a" (IS-A-Kind-of-a) car, Ford Auto "has" (HAS-A) engine, tire ... and so on. The hierarchy of "part" With the popularity of ADT, it has become a part of the software system; and "inheritance" has added "another" important software decomposition angle.