(Translation: The translation of this article is quite hard. Bjarne Stroustrup is worth opening a generation of C language, not only thinking deeply, but also in the words of the words, there are many places, the translator repeatedly considers, can not achieve the ideal effect Only the document that can only be tried to. HTML format See the Translator Home: http://www.wushuang.net If you have any comments and suggestions for this translation, please send a letter to the translation: OneKey@163.com. The address of the original text is: http://www.research.att.com/~bs/bs_faq2.html) (Dr. Bjarne Stroustrup) (Born in Denmark in 1950, graduated from the University of Arus, United Kingdom, AT & T Large-scale program design research department, AT & T Bell Lab and ACM Member. In 1979, b. S began to develop a language. At that time, it was called "c with class", and later evolved as C . 1998, ANSI / ISO C The standard is established, the same year, b. S The third edition of the C Programming Language is launched.) This is some people who often ask questions about C style and techniques. If you can make a better problem, or ask for these answers, please send me email (BS@research.att.com). Keep in mind that I can't spend all the time to update my homepage. See my General FAQ for more questions. For terms and concepts, see My C Glossary (C Glossary.). Please note that this is just a list of common problems and answers. It cannot replace a well-selected example and explanation in an excellent textbook. It also provides detailed and accurate descriptions like a reference manual or language standard. For questions about C , see "The Design and Evolution Of C ). For the use of the C language and the standard library, see "C Programming Language" (THE C Programming Language).
Directory: How do I write this very simple program? Why do you have to spend so long? Why is an empty class not of 0? Do I have to give data on the class declaration? Why is the member function not to virtual? Why is the destructor not Virtual by default? Why can't you have a virtual constructor? Why is overloaded in inheritance? Can I call a virtual function in the constructor? Is there a "Delete" (Placement DELETE)? Can I prevent someone from inheriting my own class? Why can't I define constrays for template parameters? Since there is already an excellent QSort () function, why still need a sort ()? What is a function object (Function Object)? How should I deal with memory leak? Why can't I continue after capturing an exception? Why is there a function equivalent to a realloc () in C ? How to use an exception? How to read a string from the input? Why does C does not provide "Finally" construct? What is an automatic pointer (Auto_PTR), why don't you automatically array (Auto_Array)? Can I mix use C-style and C style memory distribution and redistribution? Why do I have to use a shape to convert * void? How do I write this very simple program? Especially in the beginning of a semester, I often receive many asks about writing a very simple program. The most typical solution of this problem is to read it repeatedly, do something, and write the answer. Here is an example of this: #include To read a standard vector (Vector), you can avoid overflow errors in the buffer of the size. Read in an array, do not generate "simple error", which has exceeded a novice ability - if you have done, then you are not a novice. If you expressed this, I suggest you read my article "Learn Standard C as a new language" ("Learning Standard C As a New Language), you can list your book (My Publications List) Download it in it. Cin.eof () is a check in convection format. In fact, it checks if the loop is terminated to find an end-of-file (if not the case, then means that the input does not follow the given format). For more description, see Section of the "Stream State" in your C textbook. Vector knows its own size, so I don't need to calculate the number of elements. This program does not contain explicit memory management. Vector maintains a stack in a memory to store its elements. When a vector requires more memory, it assigns some; when it no longer survives, it releases memory. Thus, the user does not need to care about the memory allocation and release of elements in Vector. The program ends when encountering an "end-file". If you run it under the UNIX platform, "end-file" is equal to Ctrl D on the keyboard. If you are in the Windows platform, you may tend to use this slightly more complex version by using a bug, you can use the word "end" to indicate that the input has ended. #include I can't help you on the problem like this. However, this is also very likely: the program you want to compile is very bad, so that the compiler has to check the number of header files and tens of thousands of lines of lines. In theory, this is avoidable. If this is the design problem of the library you purchased, you don't work for it (except for a better library), but you can organize your own code to better, in order to ask the reconstruction of the code after modifying the code. Minimize. Such a design will be better and more maintainable because they show a better conceptual separation. Look at this typical object-oriented program example: Class Shape {public: // Interface to users of shapesvirtual void draw () const; virtual void rotate (int De degrees); // ... protected: // circon data (for Implementers of shapes) Point Center; Color Color: // ...}; Class Circle: Public Shape {public: void Draw () const; void rotate (int) {} // ... protected: int RADIUS; // ...}; Class Triangle: PUBLIC Shape {public: Void Draw () const; void rotate (int); // ... protected: Point A, B, C; // ...}; design ideas are, The user manipulates them through the Shape's public interface, while the implementation of the derived class (such as a Circle and Triangle) is shared by the part of the Protected member performance (Implement). This is not an easy thing: determine which implementation part is useful for all derived classes and shares it. Therefore, Protected members often do much more changes than the public interface. For example, although the theoretical "center" is a valid concept for all graphics, it is a very troublesome thing when you want to maintain a triangular "center" - for triangles, When it is only when it is really needed, it makes sense. Protected members are likely to rely on the details of the implementation, while Shape's users (translation: User is translated into users, referring to the code using the Shape class, but the same) is not necessarily relying on them. For example, many (most?) Use Shape's code to logically unrelated to "color", but due to the existence of "color" in Shape, it may require a bunch of complex header files to combine operations The color concept of the system. When the Protected section changes, the code using Shape must recompile - even if only the derived implementation is part of the implementation of the PROTECTED member. Thus, "INFORTION Helpful to Implement" in the base class becomes as sensitive to the user, and its existence leads to unstable and unstable compilation of user code. (When the implementation is changed), and the header file is not controlled in the user code (because "" implementation related information "needs them). Sometimes this is called "BRITTLE BASE CLASS Problem). A very obvious solution is to ignore "implementation-related information" as those in the base class. In other words, use the interface, pure interface. That is to say, the interface is indicated by the abstract base class: Class Shape {public: // interface to users of shapesvirtual void draw () const = 0; Virtual Void Rotate (int Degrees) = 0; Virtual Point Center () Const = 0; // ... // no data}; Class Circle: Public Shape {public: void draw () const; void rotate (int) {} point center () const {return center;} // ... PROTECTED: POINT CENT; Color Colories; Int Radius; // ...}; Class Triangle: Public Shape {public: Void Draw () const; void rotate (int); point center () const; // ... protected : Color color color, point a, b, c; // ...}; Now, the relationship between the change between the user code and the implementation of the derived class is isolated. I have seen this technology to reduce the time of compilation. However, what if there is indeed public information useful for all derived classes (or only some derived classes)? You can simply package this information into a class, then derived a class from it: Class Shape {public: // interface to users of shapesvirtual void draw () const = 0; Virtual void rotate (int De De De De De De De De De De De De De De De De De De De De De De De De De D) = 0; Virtual Point center () const = 0; // ... // no data}; struct common {color color color color: // ...}; Class Circle: Public Shape, Protected Common {public: Void Draw () const; void Rotate (int) {} point center;} // ... protected: point cent; int RADIUS;}; class triangle: public shape, protected common {public: void draw () const; video rot (int); Point Center () const; // ... protected: Point A, B, C;}; Why is an empty class not of 0? To be clear, the address of the two different objects is also different. Based on the same reason, NEW always returns a pointer to different objects. Take a look: Class Empty {}; void f () {EMPTY A, B; if (& a == & b) cout << "Impossible: Report Error to Compiler Suppirl"; EMPTY * P1 = New Empty; EMPTY * P2 = New Empty; if (p1 == p2) cout << "Impossible: Report Error to Compiler Suppilier";} There is an interesting rule: an empty base class does not necessarily have a separate byte. Struct x: Empty {Int a; // ...}; void f (x * p) {void * p1 = p; void * p2 = & p-> a; if (p1 == p2) cout << "Nice : Good Optimizer ";} This optimization is allowed, which can be widely used. It allows programmers to use empty classes to express some simple concepts. Some compilers are now providing this "empty base class optimization). Do I have to give data on the class declaration? no need. If an interface does not require data, it is not necessary to give data in a class as an interface definition. In order to give them in the derived class. See "Why do you have to spend so long?". Sometimes you must give data in a class. Consider the case of Class Complex: Template Why can't you have a virtual constructor? Virtual call is a mechanism that works in the case where a given information is incomplete (given partial information). In particular, virtual allows us to call a function, for this function, only know its interface, and do not know the specific object type. But to create an object, you have to have full information. In particular, you need to know the specific type of object to be established. Therefore, the call to the constructor cannot be virtual. When an object is required, an indirect technology is often used as a "virtual constructor". For example, see the "C Programming Language" third edition 15.6.2. The following example shows a mechanism: how to use an abstract class to create an appropriate type of object. Struct f {// Object set function interface Virtual a * make_an_a () const = 0; Virtual B * Make_a_b () const = 0;}; Void User (const f & fac) {a * p = fac.make_an_a (); // As a suitable type B * q = fac.make_a_b (); // uses B as the appropriate type // ...} struct fx: f {a * make_an_a () const {return new AX (); } // AX is a derived b * Make_a_b () const {return new bx ();} // ax is a derived}; struct fy: f {a * make_an_a () const {return new aY ();} // AY is a derived b * Make_a_b () const {return new by ();} // BY is the derived}; int main () {user (fx ()); // This user establishes AX and BXUSER (Fy ()); // This user establishes AY and BY / / ...} This is a deformerus of the "factory mode". The key is that the user of the user function is completely separated from the information such as AX or AY. Why is overloaded in inheritance? This problem (very common) often appears in such an example: #include However, if I need to establish a set of overloaded F () functions between base classes and inheritance classes? Very simple, use using declaration: Class D: public b {public: using b :: f; // make every f from b AvailableDouble f (double d) {cout << "f (double):"; Return D 1.3 After this modification, the output will be: f (int): 3f (double): 3.6, between the F () and D D of B, the overload is indeed Realized, and a most suitable F () is selected. Can I call a virtual function in the constructor? Yes, but be careful. It may not work as you expect. In the constructor, the virtual call mechanism does not work because the overload of the inheritance has not occurred. Objects are created from the base class, "base classes are first inherited (based on the Base Before Derive)." Take a look at this: #include Look at this specified location creation (Placement New) put the object into a series of Arena; class arena {public: void * allocate (size_t); void deallocate (void *); // ...}; void * Operator new (SIZE_T SZ, ARENA & A);} ARENA A1 (Some Arguments); Arena A2 (Some Arguments); after this is implemented, we can write: x * p1 = new A1) X; Y * p2 = new (a1) y; z * p3 = new (a2) z; // ... However, how does these objects are destroyed correctly? There is no built-in "Placement Delete" corresponding to this "Placement New". The reason is that there is no universal method to ensure that it is used correctly. In the C type system, there is nothing to make us confirmed that P1 must point to an object that is dispatched by the ARENA type A1. P1 may point to any place to anything dispatched. However, sometimes the programmer is known, so this is a way: Template This is an example: class Usable; class Usable_lock {friend class Usable; private: Usable_lock () {} Usable_lock (const Usable_lock &) {}}; class Usable: public virtual Usable_lock {// ... public: Usable (); Usable (char *); // ...}; usable a; class dd: public usable {}; DD DD; // error: dd :: dd () cannot be accessed // usable_lock :: usable_lock () is a private member (From "Design and Evolution of C Language" 11.4.3) Why can't I define constraints for template parameters? Yes, and the method is very simple and universal. Take a look at this: Template Note that this definition is thinned to the minimum: a row name to check the constraint, and the type of type to be checked is listed by the specified constraint to check the constraint to check the trigger check (through constructor) Note this definition Quite reasonable properties: You can express a constraint without declaring or copying variables, so the writer of the constraint can not use how the variable is initialized, whether the object can be copied, destroyed, and the like. (Of course, the exception of the situation to check these attributes.) Use the current compiler, do not need to define and use constraints for constraints, do not need to use the macro constraint failure, the compiler will give an acceptable error message. , Including "constraints" (give the user a clue), constraint name, and detailed errors that cause constraint failures (for example, "unable to use double * initialize Shape *"). So, in the C language, is there anything similar to can_copy - or better -? In "C language design and evolution", there is a problem in achieving this universal constraint in C . Since then, there have been many ways to make the constraint class easier to write, while still triggering good error messages. For example, I trust the way I use the function pointer used in Can_copy, it originates from Alex Stepanov and Jeremy Siek. I don't think that can_copy () is already standardized - it requires more use. Similarly, in the C community, a variety of different constraints are used; which constraint template is proved to be most effective in extensive use, and has not reached a consistent opinion. However, this way is very common, which is more common than the mechanism for constraint inspections provided by the language. In any case, when we write a template, we have the most abundant expression of C .