Among the many languages, C ++ has a very interesting position: it is built on the basis of C language and integrates the idea of simula object-oriented; it is standardized by ISO; and, it also follows the design philosophy of "you will not waste money for useless things" and "supporting user customization and built-in types are equally important. Although C ++ was widely used in OO (Object-Oriented) and Gui (graphical user interface) programming in 1980s and 1990s, its greatest contribution to software is its ubiquitous generic programming technology. Its standard template library is an example. Some updated languages, such as Java and C #, are trying to replace C ++. However, C ++ is about to release a revised standard, which adds the long-awaited new features. Bjarne stroustrup is the founder of the C ++ language, and he is still one of the strongest advocates of C ++.
1.1 design decisions
Why do you choose to extend the existing language instead of creating a new language?
Bjarne stroustrup: When I first started designing a language in 1979, the goal was to help programmers build a system. This is the case now. A language must be perfect for the application field if it is intended to truly help solve problems, not just academic applications. That is to say, the mission of a non-research language is to solve the problem. The problems I want to solve here are those related to operating system design, networking, and simulation. My colleagues and I need a language that not only represents the program structure like the simula language (most people would like to call it Object-Oriented Programming ), you can also compile efficient underlying code like the C language. In 1979, there were no languages capable of combining these two features, or I would use them directly. I don't really want to design a new programming language, but I just want to help solve a few problems.
Therefore, building a new language based on existing languages makes sense. You can use the basic syntax and semantic structure of the basic language, as well as its library, and you will also integrate into this culture. If it was not based on C at the time, I would also build C ++ based on other languages. Why did I select C? I work with Dennis Ritchie, Brian kernighan and other UNIX masters at the Bell lab's computer science research center, so this problem seems redundant. However, I am very serious about this issue.
In particular, the C-type system is non-formal and weak-forced (as Dennis Ritchie said, "C is a strong-type, weak-checking language "). "Weak check" once had a headache for me, until now it still creates a lot of trouble for C ++ programmers. Moreover, at that time, C language was not widely used today. Building C ++ on the basis of C demonstrates my confidence in the C-based computing model ("strong" part ), on the other hand, it also shows my trust in my colleagues. At that time, most of the systems used more advanced programming languages. I made such a choice based on the knowledge of these languages (both users and implementers. It is worth mentioning that at that time, most of the work was "close to hardware", and compilation was still used for performance requirements. Unix has made significant breakthroughs in many aspects, including the use of C to complete the most demanding system programming tasks.
Therefore, I chose C as the basic model of the machine, rather than a system of the "strong check" type. I actually want to use the simula class as a program framework, So I map them into C memory and computing models. As a result, it is not only highly expressive and flexible, but also fast to run, and even comparable to the assembler programs not supported by large-scale runtime systems.
Why do you choose to support multiple paradigms)
Bjarne: Because combinations of various programming styles usually generate the best code, the "best" here means that the code can express design ideas, run faster, and have the most maintainability. When people question this, they usually either define their preferred programming style and use every useful structure (for example, "Generic programming is just a way of OO ") include, or restrict the application scope (for example, "Everyone needs to use 1 GHz, 1 GB of machines ").
Java only focuses on object-oriented programming. Does this make Java code more complex in some cases, so that C ++ can replace it with generic programming?
Bjarne: Well, Java designers (probably even more so) boast that OO is ridiculous. When the so-called pure and simple Java emerged, I predicted that it would grow significantly in terms of scale and complexity if it was successful. As expected, this is true.
For example, when a value is obtained outside the container (for example, (Apple) C. get (I) will use "cast" to convert the object. This is a ridiculous method because it is impossible to assume the type of the object of the container. It is not only tedious but also inefficient. Currently, Java uses generics, so it is a little slow. There are other examples of Increasing Language complexity (helping programmers), such as enumeration, reflection, and internal classes.
Complexity is inevitable. This is a simple fact: if it does not appear in the language definition, it will appear in thousands of applications and libraries. Similarly, Java puts every algorithm (operation) into a class, which leads to such a waste: only a class composed of static functions without data. This is to use f (x) and F (x, y) in mathematics, rather than X. F (), X. the reason for f (y) or (x, y) f () is that the latter tries to express the idea of two parameters "Real object-oriented method" and tries to avoid X. the inherent asymmetry of f (y.
C ++ combines data abstraction with generic programming technology and uses object-oriented methods to solve many logic and symbol problems. Vector <t> is a typical example, where T is any type that can be copied: including built-in type, oo level pointer, and user-defined type, such as string and plural. To do this, neither the runtime overhead nor restrictions on data planning are added, and no special rules are used for standard library components. Another example is to access the operations of two classes. It does not conform to the traditional OO hierarchical model of single assignment, such as the operator * (matrix) and vector (vector, this operation is not a natural "method" of any class ".
A fundamental difference between C ++ and Java is Pointer implementation. In a sense, you can say that Java does not have a real pointer. What is the difference between the two methods?
Bjarne: Well, Java certainly has pointers. In fact, almost every operation in Java implies a pointer. They just refer to these "Pointers" as references. This implicit pointer has advantages and disadvantages. Using a real local object (like in C ++) also has its own advantages and disadvantages.
C ++ selects local variables that support stack-allocated allocation and real member variables of various types, so that it can have good unified semantics (Uniform semantics ), it also supports the value semantics concept to achieve compact layout and minimal access costs. It is also the basis for C ++ to support general resource management. This is important, and Java uses implicit pointers (also called references) everywhere to close all the doors to this.
Consider the balance of layout compromise: In C ++, vector <complex> (10) represents a handle of 10 plural arrays in a free storage area. It has a total of 25 words: 3 words for vector, 20 words for the plural, plus two headers for the free storage area (heap memory) array. In Java, it should be 56 characters (for a custom container of a user-defined type object): 1 word for container reference, 3 words for container, 10 words are used for object reference, 20 words are used for objects, and 24 words are used for free storage headers of 12 independently assigned objects. Obviously, these numbers are approximate, because the overhead of the free storage zone (heap memory) is defined in two languages. However, the conclusion is very clear: Through the ubiquitous implicit reference, Java may have simplified the programming model and Implementation of the garbage collector, but it greatly increases the memory overhead, and proportionally increase the memory access cost (more indirect access is required) and the allocation cost.
C and C ++ may misuse pointers through pointer arithmetic operations, which Java does not possess. This is also a good thing for Java. However, if the C ++ program is well written, there will be no such problem: people use higher-level abstractions, such as iostream, containers, and algorithms, rather than using pointers. Essentially, all arrays and most pointers should be hidden in implementations that most programmers do not need to see. Unfortunately, a large number of poorly written and redundant underlying C ++ programs are everywhere.
However, it is very convenient to use pointers (and pointer operations) in one important scenario: direct and efficient data structure expression. It is not referenced by Java: for example, you cannot use Java to represent exchange operations. Another example is to simply use pointers to directly access the underlying (actual) memory. For each system, some languages have to do so, and this language is usually C ++.
The "negative effects" of having pointers (and C-style arrays) are of course potential misuse: Buffer Overflow, pointer pointing to deleted memory, uninitialized pointer, etc. However, in a well-written C ++ program, this is not the main problem. You just don't have to deal with the pointer and array (such as vector, string, and ing) used in the abstraction. Resource management with a limited scope meets most of the requirements; smart pointers and dedicated handles can be used for most legacy issues. It was hard to believe that people who used C or the old version of C ++ used it in the past. However, the limited scope-based resource management tool is very powerful and user-defined, you can use less code than an insecure old-fashioned hack program to solve classic problems. For example, the following is the simplest form of typical buffer overflow and security issues:
Char Buf [max_buf];
Gets (BUF); // yuck!
Using a standard library string will solve the problem:
String S;
Cin> S; // read characters separated by Spaces
These are obviously inconspicuous small examples, but the use of the appropriate "string" and "Container" may basically meet all requirements, and the standard library can also help you easily get started.
What do you mean by "value Semantics" and "general resource management?
Bjarne: "value Semantics" usually refers to a class in which, when copying an object attribute, you get two independent copies (with the same value ).
Of course, we do this for common numeric types, such as ints, doubles, plural, and other numeric types, as well as mathematical abstractions such as vectors. This is a very useful idea. Here c ++ supports built-in types and any user-defined types we want. It is very different from Java. JAVA supports built-in types such as char and INT, but does not support user-defined types. In fact, it does not support those types. As in Simula, all user-defined types in Java have reference semantics. In C ++, programmers can also support reference semantics if a type of semantics is required. C # (incomplete) complies with C ++ in terms of user-defined types with value semantics.
"General resource management" refers to a popular technology that allows an object to possess a kind of resources (such as file handles or locks. If the object is a variable with a limited scope, its life cycle is the maximum limit on the resource holding time. A typical scenario is that the constructor Obtains resources and releases resources. This is often referred to as raiI (resource acquisition is initialization, resource retrieval initialization), and it will be perfectly integrated with exception handling. Obviously, not every resource can be processed in this way, but there are still many resources that can be used in this way, and for those resources, resource management becomes invisible, efficient.