YTread Logo
YTread Logo

The Design of C++ , lecture by Bjarne Stroustrup

Jun 06, 2021
Hello, I'm Piana. I'd like to tell a little about C++, why the language looks the way it does, and present some of the main techniques the language was

design

ed for. The talk has three main parts first. I'll talk a little about the origins of C++, the problems the original

design

was meant to solve, the goals I had for the design, and present some of the rules that were developed for the design of the language. Below I will introduce the key techniques. programming techniques that the language supports and the language features that exist to support that type of programming, that means things like classes, abstract classes, derived classes, uses of class hierarchies, templates, runtime type identification, and Finally, I will introduce some features specifically. designed to support writing larger programs, i.e. namespaces and exception handling towards the end, I'll look a little at how C++ is currently used and how it could be used in the future.
the design of c lecture by bjarne stroustrup
My main idea about languages ​​is that a language is someone's answer to a set of problems at a given time, a language is there to solve problems rather than being an interesting thing in its own right, our problems and our understanding of those problems change naturally over time and to the extent that as a language it is a good solution to the problems that real programmers face in real code uh the language will live and grow to meet the needs of programmers um the origins of C++ uh go back a long way uh one of the direct C++ courses was a project that I worked on at the University of Cambridge in England, where I was working on my PhD.
the design of c lecture by bjarne stroustrup

More Interesting Facts About,

the design of c lecture by bjarne stroustrup...

I was studying distributed systems and the distribution of software that runs on those systems. I built a simulator to give me data on such systems in which this simulator was written in simula was, for the moment, at least a fairly complicated program that I had come across before with simul, but I was pleasantly surprised when I used simul uh not only it allowed me to write my program, it also helped me think about the program design, the concept of simulation class, the way you could develop the classes, the simultaneous routine mechanism, everything helped me organize my thoughts, secondly , the debugging of that program was quite nice and strong.
the design of c lecture by bjarne stroustrup
Type checking helped me a lot and made sure I didn't break my own rules as I had built them into the program in the form of classes. Actually, the amount of help I received from the strong type system was a surprise to me because I previously came across Pascal and found its strong type checking to be quite counterproductive. It always seemed to me that type checking checked some set of implementation-directed rules that got in the way of my programs. The difference between simula and Pascal was that the rules checked by simula were generally the rules for the user-defined type.
the design of c lecture by bjarne stroustrup
I had definitely found the classes and when strong type checking found something, it tended to be a violation of my own rules and I couldn't. I'm too opposed to that, so I wrote the program, debugged it, it worked quite well, unfortunately I ran into a major problem: the runtime of that program, the actual runs, as opposed to the debug runs, were quite extraordinary and it was absorbing my apartment. I calculated the budget pretty quickly on our mainframe, so I had to find a way to make this program run more efficiently, or I'd have to leave Cambridge without a PhD.
Now there are a couple of classic solutions to this problem, like I could get my own computer, but that wasn't entirely feasible because a computer like that cost several million pounds and I certainly didn't have that kind of money. Alternatively, I could wait for the hardware to get cheaper, but that would have taken at least 8 years or so, I could try to make Simul run more efficiently, but I had the utmost respect for the people who had designed and implemented simul. and I knew they were probably better than me at that job and anyway my job was It wasn't to invent languages ​​or implement simulations it was to study distributed computing so in the end I decided to rewrite my simulator in bcpl and run it on a machine The main machines couldn't use it. uh, bcpl is a direct ancestor of the C language and it's a language that makes C look like a very high-level language.
Getting my simulator rewritten in bcpl and running it on a research machine was quite a pain. uh, debugging was hard, in fact I lost about half my hair in the process of debugging that program, but there were some real advantages: the simulator ran very fast so I could get my data and the problems with bcpl were all overcome , were not important, there is no Co CH in btpl, so we added things like that to them. This led me to some ideas of what was important for a tool to work in systems programming in general. I wanted a tool that provided support for program organization uh that simulation provided help in thinking, help in designing that simulation provided, on the other hand, I wanted something that ran very fast when you had to like bcpl or C.
I wanted something that It was easy to carry. that required uh not much support from the environment um and uh preferably something that was available these ideas later came in very handy when I found myself involved in studying some things at Bell Labs U a little later um there I developed a language that was initially called C classes that were intended to provide help for designing, thinking and organizing programs from simula uh, but with the efficiency and flexibility of the U of Cu uh, there are two questions that are often asked about C with classes and then with C++, the first is y c and the other is why similar classes are similar.
I chose C mainly because it was the best systems programming language available. C is flexible, you can do whatever you want with it. It is efficient if you know how to use it and it is reasonably portable, it is available on most machines and most importantly it is known by most people in this area, if you want to create a new language, a new system, it is quite useful not to have to reinvent every wheel, so I took the attitude that computing as such was a problem solved by Dennis Richie in the design of c and my business was the organization of programs, clearly C is not the language most beautiful that exists. many failures, but there are second-order failures.
I think the C declarator syntax and experiment failed, but it's not critical. I've never met any halfway competent programmer who couldn't master what they needed to master about C syntax in a couple. Within days or a couple of weeks, the only thing that really bothered me and had anything to do with the way programs are written was cy's weak typing system, so I proceeded to improve type registration static. C, so C++ is strongly typed. Classes came as the primary means of organizing programs. The idea is that you organize your program by looking at the application area, look for the fundamental concepts in an application area and try to map them into the program in the form of classes, that is, user-defined types, and use verification of static types to check that you have used user-defined types according to the rules you can derive from what fits the concept.
I note that reuse was not a primary priority. mine, there is a lot of talk about object-oriented programming and reuse and reuse is something that you get if you have a set of well-crafted and well-present concepts represented in your program, then you can reuse those classes or those collections of classes. It's not something that magically arises from language features, it's something that arises from thinking clearly about problems that becomes useful. Concepts isolated and clearly represented. I developed C and then C++ classes at the computer science research center at B Labs in Murray Hill, which is in New York.
Jersey in the United States and I think my work environment there was very important in the sense that a language will reflect the environment in which it is created and the type of uses that are put to it in that sense. Language is like any other large system. Work in those days was a little bit of everything. Many different types of work were done in the laboratories. My main job was not to design programming languages, but to work on myself. The work had a lot to do with simulations of things related to distributed systems, so a lot of the information for the design of the C and later C++ classes came from people who were dealing with systems programming, dealing with distributed systems and they were dealing with network design and they were dealing with designing uh vsi layouts and dashboards, things like that, um, there was a lot of emphasis on doing things that were useful to colleagues in general, useful to other people around, so On the other hand, there was freedom from deadlines, no one told me when I had to deliver the next release and, very importantly, there was freedom from the feds and commercialism, I didn't have to produce something that could sell, that fit nicely into glossy brochures and I didn't have to produce something that would please academic critics interested in the latest intellectual developments.
I could focus directly on the programmers, writing the production code, not on the advertising, to the managers or, um, some kind of Academic Fashion Keepers, see, with the classes it was a medium success and that worked out. It turns out to be a problem, a medium success is something that is clearly a help for many people, but not enough help to pay for infrastructure; in other words, someone who produces an average design will end up supporting it forever, so there was the support and development organization for SE with classes and it would remain that way for a long time, since I was not very interested in doing maintenance and support of direct line for the rest of my life, I was looking for a way out of the dilemma and it seemed to me that there were exactly two ways out of the dilemma: I could improve the language so that it could provide more benefits to users, allow people to write better the code, make it bigger. changes in their organizations, that would make the language more popular, it would get more users and that would allow it to pay for the infrastructure it needed, it would support the teaching of development, the compilers would support that kind of thing and the alternative was, of course, to stop supporting SE classes. and then the users would leave and that would solve the problem.
On the other hand, the users were my friends and simply leaving them without them didn't seem to be fair at all. I later found out that it was actually a third alternative, but I'm kind of glad I didn't think about it at the time because the third alternative, which is kind of a conventional solution, is just adding advertising, more advertising, more glosses to convince people to use it. but fortunately I didn't think about that at all um when U designed the C classes some criteria for what uh was useful uh I developed actually the origin of that goes back to my work with simul and pcpl and over the years it grew into a set of rules of thumb, you could call them principles, but that sounds very pretentious, so I'll stick with the general rules, first of all, C++ is a language, it's not a complete system in the sense that it differs from the people who try to provide it. a complete environment for programming and use as is common in the world of lisp or small talk.
On the other hand, it has the effect that if you work in C++ on a Unix system, C++ will sound and feel like a Unix language will have the user interface that you have on your Unix system will have the libraries you are used to will have the feel of Unix if on the other hand you work in Dos it will feel like a Dos language and presumably you like the system you are working on so that's fine, it also simplifies portability because you only have to port the language, you don't have to port a user interface and an operating system, as the classical distinctions between language, environment and libraries are deliberately maintained.
An important rule in the design of C++ as more features were added was what we called the zero overloading rule. What are you doing? What you don't use you don't pay for. C++ has some semi-advanced features and can be a little more expensive to use than the simpler features, but it was very important to us at the time that not only should you be able to write good programs in C++ but you should also be able to afford them. write good programs and for that reason you should be able to do simple things simply and cheaply.
Very important was the concern about real programmers, that is, the language was designed to solve the type of problems that programmers faced now, the type of programmers we had.using the type of systems they were actually using. um, it wasn't a language designed to be the best language for the interesting problems that programmers might face in the future and could handle if they had had this wonderful education. that people might have in the future and had at their disposal the computers that would undoubtedly be available. The focus on being useful now in current uses was important and has been essential to the development of C++.
I also had to remind them. I very often don't try to design the perfect programming language. I must not engage in a fruitless pursuit of perfection. For the simple reason that people's programs and ideals about what is perfect are chained together, and therefore, when something is perfect, the world. has changed, so it's imperfect relative to that world, it tries to do things as best as possible, it obeys whatever principles seem reasonable as much as possible, but we couldn't just wait to stop programming for five or ten years until the perfect language was available. This led to some restrictions in the design of C++, for example.
I decided to use traditional linkers. I don't really like traditional linkers, they were designed to link Fortran with Fortran 2 and do it reasonably well. Modern languages ​​are very different and using old, dumb linkers is quite restrictive, on the other hand if we didn't use traditional linkers I would. I had to provide a new Linker for the new systems we would be working on and I would spend all my time writing links and portability would be difficult. Education would be difficult, so stick with the old links and another thing was that I didn't really want. being in charge of teaching people a completely new programming language that I was relying on so I wouldn't have to teach yet another way to write a for loop, so the rule of the game was no tipping or comps with c um, the main An example of an incompatibility that is not free is a violation of the static type system.
I systematically remove violations of the static type system, and when I cannot completely remove a way to violate the type system, I provide an alternative that does not require a violation. Another technical rule that was useful was that the language should provide the same support for built-in user-defined types as a user. You shouldn't care if the type was invented by Denny Richie when I designed C or by me when I provided a standard library or by you, when you wrote your application, the rules for type checking scope, assignment deallocation, all that should be the standard, the rules of the language that emerged from these rules.
C++ and I guess the best way to describe C++ fundamentally is to go to an executive summary which I was once asked to give about C++ and being a young researcher I had no idea what an executive summary was so I asked someone who I was Supposed to Know and I got the response that an executive summary is something that fits on half a sheet of paper using very large font and I thought about that a little bit and came up with basically a three line description of C++. C++ is a better C, it supports data abstraction and supports object-oriented programming.
I guess if you're a senior executive, that's enough to understand the problem, but I guess I should explain a little more. C++ is a better C by pretty strict criteria about what is better and what c means, first of all you should be able to do in C++ everything that you can do in C and you should be able to do it more or less in the same way and approximately without reality and with the same efficiency, that is, I can't improve C by making it better by making it look radically different by slowing it down by removing facilities uh, uh, I thought you probably didn't want to use it anyway, um, so it didn't, I can add some notations conveniences, that That's all, the efficiency argument was taken quite seriously.
For example, we once discovered a systematic overhead of about 3% in C plus no C programs with classes compared to C for programs written in the common subset of those two Langs. This was considered unacceptable and the overhead was removed. There is no overhead in a C++ program compared to a C program for a program in the common subset. That's important to a lot of people. U support for data abstraction is where the new things begin, this is where the real benefits start to come, the idea is that instead of just writing a program, you separate the design, the programming technique, the process of programming in two parts, first design a set of types, a set of classes that is intended to map the concept in your application, in other words, if you are an engineer, if you are a mathematician, you may find that the fundamental concepts in your world are things like matrices, complex numbers, triangular matrices, strip diagonal matrices, four-year transformations and then let's say these are the key concepts, you build classes that represent those concepts and after you've built this foundation for your application you basically build an extended programming language, extended to suit your needs, then you can write your programs in that language, if on the other hand your application area is different, you will use a different set of user defined types, let's say you are making changes, probably you have buffer lines, trunks, switches as fundamental types in the graphics application, you will have shapes, you will have circles, rectangles, triangles, smiley faces. it faces what I know um languages ​​like track and Ada was designed to support this type of programming this type of approach to programming um however it was discovered even in the early days um of simulation that um just being able to do that was not enough to properly map the way we think about things in a programming language uh, we needed to not only be able to represent concepts directly as types, we wanted to be able to represent relationships between concepts as relationships between types, uh, let me give you, what?
What I think is actually the original example of this, someone wanted to plan emergency services for a city, the idea is to write a simulator that simulates traffic in a system and try to place your emergency services, fire stations, police . stations in such a way that it minimizes the time it takes to respond to an emergency, so start simulating the city, you will have streets and streetlights and police stations, fire stations, hospitals and on the streets there are things like cars, patrol cars, trucks, ambulances, buses. fire trucks and you simulate your traffic patterns and you see what design and what kind of dispatch rules will make the fires go out faster and that now, one thing that you will notice if you do that from the data abstraction of a data The abstraction point of view is that the code becomes quite clunky.
You come down the street in some kind of vehicle and you have to type the code to turn right and you will end up typing something like um if you are an ordinary citizen. the car turns right the same way regular cars turn right if you are a police car turn right the way or police cars turn right if you are a truck turn right the way way uh the trucks turn right if you're a fire truck turn right in the direction of fire The engines turn right and this is necessary because fire trucks, trucks, police cars and cars Normals are different types and you have to write different code.
On the other hand, it's pretty silly because, all I wanted to say is turn right in the direction you want. turn right and you clearly shouldn't be on the streets unless you know how to turn your vehicle right, on the other hand they turn right in different ways, a regular car, at least in a European city, will stop at red and the police The car will probably turn the corner because it has special rules on the road. A truck takes a much bigger turn, otherwise you're probably going to miss something standing on the sidewalk, so what we had to do was be able to classify our types the way we classify our concepts and say well, let's look at buses, trucks, and trucks. firefighters, well, they're like trucks, uh, police cars, ambulances and normal cars.
I like normal cars and they are all vehicles, so you build hierarchies of types and then you say, well, actually it is common that all vehicles can turn right and you should be able to write the code in the vehicle that turns right and make the vehicle turn right the right way and, uh, the facilities to do that, um, were built in simula from the beginning, so it's a very old technique from at least 1967, the work was done in Oslo um and uh, I just picked up those ideas uh this is generally what is known as object-oriented programming, the C++ version of these ideas uh comes with an emphasis on support for design, I mean designing from the principle rather than just playing with some code and seeing how it runs.
You can do that too, but the idea is that you do a little work from the beginning and provide a design. an emphasis on static structure and static verification IT. The idea is that anything the machine can do for you and anything that can be done early is preferable to procrastinating or leaving it to people. There was quite significant concern. The concern about runtime efficiency and space compactness, this comes from the fact that a lot of the uses I saw for C with classes and C++ were in areas where time and space were quite critical, simulations, all kinds of things, no. just cities, how about vsi design?
You might have a couple million objects in a simulation like that. You have to find the design. It depends a lot on both time and space. Graphics and basic system programming tasks, such as device drivers. Network protocols and things like that, clearly, since the C and C++ classes were new languages, you had to coexist with the existing languages, otherwise you couldn't use the new language until you could do everything in it and that didn't seem nothing sensible. The idea was to fit with other languages ​​and fit into existing systems throughout the design. I valued experience over theory when there was a crash.
The theory is all very well, but it is never a sufficient reason to accept the feature in the language. It seems to me that people can argue convincingly for every feature and every technique and a pragmatic approach is needed to prevent good ideas from ruining good work. I'm going to talk about the language features provided to support the Basic Techniques The first set of techniques I'm going to talk about is how to define user-defined types to meet the needs of a programmer. I'm going to mention three things in that context. Classes have abstract classes and templates. let me first show you what a classic user-defined mathematical type looks like, i.e. a complex number.
The word for user-defined type in C++ is class. The word is taken from simula. I don't like to make up terminology if I don't have to. direct descendant of simul in many ways I use terminology uh the CL class complex is something that is used in mathematical engineering uh programs uh people are used in those fields generally for Fortran and uh the C++ code that you write has to coexist with Fortran, so that we Define a complex number as something that is represented by two double numbers of precision points called Real ray and M, the real part and the imaginary part of a complex number, that is the representation and it is private that you cannot access . except through uh operations to create a complex number you have to specify one double or two doubles if it's two doubles, that of course gives the real and imaginary part if there is only one, it's a real part and the imaginary part becomes zero , comes straight out of a math textbook, the idea in designing C++ was to provide something that was as close to the application domain as possible, in this case as close to the math textbook as possible, so, If you have the representation, you can construct complex numbers. all you need are the usual operations like uh plus and multiply and then you can look at a snippet of uh user code uh and it will look like what user code is supposed to look like: you declare some complex variables and initialize them with floating point numbers or pairs of floating point numbers and then you multiply them and add them and multiply them with floating point constants Etc.
Basically, it is a very restricted exercise. Code written using complex variables has to look like it's supposed to in Fortran or C. It looks like integer arithmetic and that's how it works. The complex numbers example demonstrates a couple of important properties about C++ and the way classes can be defined, for example, almost no compromise with conventional notation was necessary, here's what the code looks like. the way it was supposed toSeeing the code, someone familiar with complex arithmetic can read the code without having to know much about C++. I recently saw an interesting example of a piece of C++ code that was immediately readable by someone who didn't know C++, but knew the area of ​​physics they were dealing with, while I couldn't read it.
I only knew C++. I didn't know the correct physics, so this mapping, the direct mapping, is very important, no commits are needed in the complex example and overall few commits are needed, also there is no real commit at runtime, code written in C++ this way will typically run maybe 25% less than Fortran, it's very very difficult to compete with Fortran and in this particular case. 25% is acceptable, you can do better if absolutely necessary. There are ways to adjust the code. One thing that makes this possible is insertion. It is not necessary to have simple operations like constructing complex numbers and adding them as a real function. call the compiler can and does, if the data structure had not been a complex number it could have been, for example, the time of day structure, known to an operating system, design compatibility with C becomes essential if you don't have it. you have to do a format conversion every time you talk to your operating system or your computing library and that's generally not a very good idea, compactness of space.
Also matters, a complex is represented as two floating point numbers and the size of a complex number is the sum of the sizes of the two floating point numbers uh, not the sum of the two floating point numbers plus some housekeeping information if you have a lot of complex numbers, millions of them, that's important if you're dealing with a graphing system, um with a few million points that you don't really want, extra overhead on your data structures, the whole issue of efficiency and compatibility, design compatibility and so on, is very important in a transition period. You want to be able to afford to use a new language.
You want to be able to compete with older languages, but you also want to coexist with them because there are things that new languages ​​don't do. as well as the old ones or they still don't work as well as the old ones and even if they did much better you still wouldn't be able to replace the old code immediately, a gradual transition is very important now, this is all very good if you care about the old code and many people at least claim that they don't care about old code. I mean, they want something new and much better, and the usual comment on this is yes, but these data types are maybe user-defined, but they are not abstract data types, you don't have a separation between the implementation and the interface. .
You can't change the representation of a complex number without having to recompile the entire world and I don't want to recompile the entire world now, my answer. That's why it's double, first of all, for things like complex numbers. I am willing to recompile the entire world. In fact, my complex numbers have not changed their representation for the last 12 years and I am willing to recompile my world every In fact, 12 years, I am usually willing to recompile my world at least once a year, but yes, there are types that change their representation much more frequently. In fact, there are types that you want multiple representations of. and you don't want to bother the user with knowing what the representation is, so let's try to build a truly abstract type in a type is abstract, if you can't tell what the representation is, you can only see an interface and uh We can define one of those.
I will define a set and if you look at the definition of the class set you will see that it has to be abstract because there is no representation specified and since the representation is there, the user cannot. We depend on it in unwanted ways and we may have alternatives. All we have in this set of classes is a set of functions that specify what the type is and how the set should behave. There is an insert operation to paste new ones. elements in there is a delete operation to remove them again there is a query operation to see if something is a member and um just for compactness I provided a couple of operations to iterate all the members of the set a first and the next operation now if If we have a type of this type, we can use it and a user can use it using only the specified interface and the code will look quite conventional um, the my function takes an array as its um as an argument and iterates it presumably doing something with all the elements, everything What the user can do for the iteration is request the first element and then continue fetching the next element until it runs out and it's a perfectly conventional C4 statement and we use only the abstract type the interface is visible to the users that's all the users can do.
Users know is all users can use now, of course someone has to know what the representation is, you can't create a set without saying something about what kind of set you're supposed to have. say not just what a set is but what its representation is so someone can use my code giving it a couple of sets and this example here is someone making a set of lists S and a set of vectors and presumably those are types of sets implemented with individual linked lists and arrays and you can pass that to my code, this is fine, my code gets a set sist, my code gets a set of vectors and it works correctly, in fact when I wrote that code I had no idea what set, there was actually um, the user who creates those sets, of course, has to have access to the definition of ses set vector set, but they don't really have to worry too much about what they are, on the other hand, someone has to define the sets and if you look at a definition here we have an example of how to define a set of lists uh s uh a sess set is a set that is a set that is its interface and is implemented uh, we can see in the definition of sess sets that it is implemented using sess set and you have a current element which is a representation, but what's really important is that it defines all the operations that a set requires.
An abstract class like set specifies that certain functions must be provided and in this case, if you forget to define one of them, the compiler will detect this and make sure that you do not create objects of a type that does not actually provide the functions that its interface provides. , so it is shown in the example set. how you can separate the interface from the implementation and also showed how you normally use a data type that doesn't have that kind of separation in the implementation part so that you can use the other type of classes, those where efficiency and compactness is important to implement those where spacing matters uh there's just one thing that's a little unrealistic here, you don't actually want a set of T as I definitely find it, at least not unless T is one of your favorite data types that you want uh sets of, say, complex numbers sets of pointers to shapes sets of um some data types that I've never heard of because you're only going to define them tomorrow in other words, you want T in the set example be a uh, a parameter that you can specify so that you can create sets of different types um, um, I wrote an example of how to do that.
I used a stack instead of a set, um, it's a perfectly ordinary stack, it's written in terms of stacks. of something called an element type called T and then I just prefixed the uh stack def statement with the template class prefix T and that says that it's a stack template and that uh that t is a parameter um so you can do individual classes of this template as integer stack star-shaped complex stack stack and the language will ensure two things: First, it will ensure that specific classes, such as integer stack, behave the way a stack should. integers as per the definition of the stack template, furthermore it will also ensure that that class is generated in the proper way, let me give you an example of how this works.
I'll take a stack of pointers to planes and it's the job of the language to make the code work as long as you've used it only in the appropriate way for plane stacks and I quickly started using it wrong by pressing a Sab uh 900 and a Sab 37b now a sa 900 if it's at all reasonably defined it's not going to be an airplane a sab 900 is a car um so the rules of the language ensure that you can't push it over a pile of airplanes the sa 37b is fine though because a 37b is an airplane recognition, so when I try to write the code pushing the U the 900 onto the stack it won't work.
I will get a compile time error. This contrasts with the use of um. Dynamic type checking in some languages ​​is like the list variant. and a small talk where you just say: I want a stack, a stack of whatever you want and I can push anything on the stack, so here it would work to push a stack to 900 and push to 37b, that's fine, you'll do it. catch the error later when you try to misuse the object like when you pop the stack and ask the last thing that was pushed to take off, that will work fine because the last thing that was pushed was a sa 37b which is a plane if you try to do it again by taking out the Sab 900 uh things are not going to go so well uh a 900 is fast but it's not going to stay in the air so you get a runtime error uh and presumably you're in a Very good debugger .
This is fine if I'm debugging my code. Finding the error while debugging. IMO it's not as good as a compiler finding it before debugging, but it's pretty acceptable on the other hand. You were debugging your code and it was part of my code that generated the error. You might be less tolerant and if you are a user of the application and not a programmer you might get quite angry, so you have a trade off where you will find your mistakes and consistency consistently design decisions and C++ has gone towards early bug finding using static type checking basically classes and abstract classes and templates support the notion of data abstraction, that is, the ability to take some kind of concept and represent it in code as a type, which What we must do to get to oriented programming is to be able to represent class hierarchies, represent the relationships between different types and I will show two ways of using it in C++, the first is to build types in stages and then take advantage of the way they were built, for example , you can have a class shape and the shape has some properties, like shapes have a center and shapes can be rotated and drawn, but basically you can't give more properties than that for a basic shape like you don't actually know how draw a shape in general because general shapes cannot be drawn you can only draw particular shapes so the draw and rotate functions are defined to be virtual it will be defined later when we know what to do then we can define a circle and a circle is the type of shape that has a radius and is drawn the same way circles are drawn and rotated in the obvious way. that doesn't do anything and then you can build again on top of that, um, you can build an emoticon, an emoticon is the type of C that has two eyes, they have two eyes and a mouth and once you've defined this class hierarchy, you can start to use.
In code, a library code snippet could be written simply in terms of shapes and I have some kind of imaginary library, a code snippet called rotate that takes a set of shapes and rotates them by various degrees, we use the properties of the set of abstract classes so we can um. You can iterate through the set regardless, of course, of the type of set we are dealing with. This set could be a sess set, it could be a vector set, it could be a type of set that I had never heard of uh, when I wrote the library code, it doesn't matter and then each of the shapes you get, we ask rotate the right number of degrees and, well, again, we don't, we don't have to know what. type of shape is uh the shape that comes could be a circle could be an emoticon could be a map of the city of Manhattan uh I don't know, a user can create a particular type of set, fill it with shapes and pass it to the library code and this will work even if the library code is compiled before the particular type of set has been invented and before the particular type of shapes that are placed in the Set have actually been defined, those are important. degrees of freedom for a library designer, and what it relies on is that both shapes and sets conform to the interfaces we have specified for them, this is the basic way of using C++ class hierarchies, a sometimes it is not enough. when we start using libraries when we have large software systems made up of classes and defined by different people at different times we sometimes give an object of a type that we know or to someone else and then we get it back later and um we can pass a um Smiley to a graphical system and it is possible that they will return it to us, but since thegraphics will be written in terms of the basic abstractions available in graphics like shapes and I don't know anything about um My little shapes, that happens. to like the Smileys uh, when it's returned to me, the exact type has been lost and sometimes I just have to be able to ask now if the shape that's returned to me is actually mine and that's done by something called a runtime type. query uh, here's an example of a dynamic cast where I get a shape.
I ask if it's a smiley, if it is a smiley I get a pointer to a smiley, if it's not a smiley I get a zero and can therefore test if it was a smiley. I do what is appropriate for emoticons. Yes, if it's not, I have to do something. This becomes quite significant when dealing with event-driven systems and if dealing with large standard libraries. If you think Smiley is a bit of a frivolous example, think of it as a dialog box or an event that has been fired, one of many events that the system could respond to um in um in in a real sense classes and classes dve hierarchies of runtime classes Type identification supports writing large software systems.
There are also features in C++ that have appeared over the years as systems built in C++ have grown and are designed specifically to support users of large systems. large systems, I will describe Nam spaces and exceptions here. Now the problem with namespaces is that people writing code will use some names, and if there are a lot of people writing code, they will accidentally use the same names. uh for different things, like they're all going to have functions called Draw and open plus and so on, they're going to define classes called strings or something complex like that and somehow or another we have to make sure that the names and the things that I name don't.
They don't clash with the names you use for things you need, and the basic mechanism we have is called namespace. I put my names in my namespace and you put your names in your namespace and the net effect is that the two don't collide even if a third person uses her code and my code. The only problem left is that we have to make sure that the user can also use our names and the basic way to do that is to just say what names he wants to use, like if I want to use a string, I say colon, colon string which is pretty obvious and if I want to use function f from B, I use B colon colon F if that gets tedious you can say that, well I want to use names from namespace B and that means if I use a simple name as string, it will be uh string B uh the other way around, you could say wellI just want, I would just want an f as well and um that means if I use f it's ASF um pretty simple and simple mechanism, it's all compile and link time, but it beats a pretty serious problem found in languages ​​that don't noticeably have it.
C and C++ in older versions, now this allows us to write code that is developed separately, merged without name conflicts, allows us to interact with classes and derived classes, allows us to represent concepts directly, the only problem is that when you start Writing code this way, some errors remain to be caught at runtime and the problem becomes how to report and how to handle the errors that are caught. A library can of course detect errors that occur at runtime as if you have an array class in a library that array class can detect an out of range access which is quite easy, on the other hand it doesn't know what to do when you get an out of range error, only the user knows what he should do.
This happens, I mean, maybe it's critical that there's an out of range error, um, maybe it's not, if it was just a piece of data collection code and you were trying to write outside the edge of a matrix, it should simply be ignored, that's enough. acceptable in some cases, but you certainly shouldn't start writing to the wrong part of memory so that libraries can catch errors and users can specify what should happen when errors occur. It's a difference between a mechanism and a policy, so we have the situation. that a user can tell if I make a mistake doing over there.
Error functions must be called. Every library ever written has something like this. The problem is that most of two different libraries usually use a different type of strategy and if someone uses multiple libraries and has to deal with several different error strategies the code becomes unmanageable, we need a fairly standard way of dealing with errors detected at runtime and that mechanism is known as exceptions. The way you write it is you write something called a tri block and any code that runs in the tri block or is called from the tri. block um, you can check if certain types of errors occur in unusual circumstances, in this case, here I say that if an IO error occurs, I want to know about it, so if an IO error occurs, in the code, in the triple block or o dynamically next I will find myself in the Handler uh catch I ER, it is called so we go and execute the code and we lower it to this function H that does some iio, checks if everything is okay and finds that there is an IO buffer uh it is overflowing and throws the specific IO error um buff overflow now this error propagates this exception propagates to the catch block and realizes that a buffer error buffer overflow is defined as a type of IO error and we catch it so There are two things that are important about this code: first, we can detect IO errors;
Second, we don't have to know the details of IO errors. uh we'll catch any IO errors whatever you call it, basically we're using class hierarchies, derived classes to express the grouping of different types of errors and that's an important degree of flexibility in how you handle errors, both by the characteristics of the language as well as by programming techniques. A question I get asked quite often is how, why and where he did it. C++ got used to it, why did it grow? First, it grew without the use of advertising and marketing in the traditional sense. In fact, for the first three years, AT&T's advertising budget for C++ was $5,000 and we wasted $1,000 on a letter to system administrators that no one read, and the next 3,000 were used at a reception at the first C++ conference, that too. helped C++ but we had a good party and the rest we had to return and we couldn't find a good use for it, on the other hand, not having major overheads meant that the price tended to be right and we tended to encourage self-sufficiency among the users, which was very important, we also had a strong emphasis on portability, the average time to port to a new system for someone who didn't know C++ was about a week, the record was about 3 hours for someone who was moving to a completely new system without knowing C++.
C++ was powerful and expressive compared to traditional languages ​​like C and Pascal, and it was fast, compact, and cheap compared to anything that had abstraction mechanisms that put it on par with C++. The growth of C++ was always global, with users basically everywhere, but the emphasis was on the US technology-oriented industry, but there had always been strong use in various industry sectors and in academia. . Basically, I guess the reason C++ was a success is that it is a very practical general purpose programming language with an emphasis and strength on systems programming. You can do various types of programming in traditional C++ C such as programming data abstraction techniques and object-oriented programming, but no one forces you to do it and you can do it in a variety of environments.
Basically, C++ was successful because it addressed real needs of real users and I certainly grew, um. I tended to try to count C++ users and at the end of 1991 I stopped because I couldn't count users anymore and at that time there were about 400,000 C++ users, um, it's very difficult to get hard numbers there, but but. I know that the most popular C++ implementation has sold 1 million copies, so we're dealing with pretty large numbers, with a lot of implementations and a lot of users, we need some kind of standards effort and that started in late '89. and the American national standards organization and the ISO, the international standards organization, came together in 1991, the initiative was taken by IBM Deck and HP, basically to prevent chaos from breaking out and to make sure that the language was under standardization, this created a forum for debate and dissemination of ideas, that is very important to stabilize the language and make sure that the language responds to broader needs and, more importantly, make sure that no company exerts undue influence on the language.
Clearly, standardization is not easy. people have to agree and it's especially difficult because the language is still evolving. There were people who considered C++ standardization premature at the time because core features like exception handling and templates were new at the time, but we hope to get standards. uh soon and the draft standard is June-September 1994 uh the main challenge has been making Main a coherent language and I think we've achieved that so far. There are no features in C++ that I don't think should be there and I don't. losing important features in the language for the type of uses that I consider, the challenge in the future is mainly education, that is, you can do a lot with libraries, you can do a lot with design tools and techniques and environments, but fundamentally the main thing.
The challenge is for programmers and designers to learn to use the tools we have well and design and implement systems using the facilities we have. C++ has some real strengths in low-level systems programming and also higher-level systems programming and its use is aimed at creating general applications and also numerical scientific engineering applications. The greatest strength is probably in systems that have a combination of everything. If you have a system that has to do some database work in a main framework, you should do it. to do some networking, you have to run some gadget like a trader, a stock trading platform and you have to do some visualization on a mini computer uh um superc. uh, few languages ​​can do all that and C++'s biggest strength is in, I think, areas where you have a mix of challenges and a mix of application areas, well basically, I think C++ is still very young, it's a young language. and we have only just begun to see the benefits we will reap.
Thank you for using it

If you have any copyright issue, please Contact