- C++ is a general-purpose, compiled, and case-sensitive programming language.
- In order to write programs in C++, you need to be familiar with its syntax. Anyone interested in learning to code in C++ can consult reference works like Stephen Prata’s C++ Primer Plus.
- C++ was originally unveiled to the world in 1985 as the brainchild of Bjarne Stroustrup at Bell Labs.
What is C++?
C++ is one of the best-known and most ubiquitous computer programming languages in the world, casting a long shadow over the entire history of computer science. Even now, nearly four decades after its initial emergence, it continues to be extremely popular. It continues to loom large in an impressively diverse array of fields and be put to a dizzying number of uses.
What explains this remarkable longevity? In a word: power. The simple and raw fact of the matter is that C++ is an astonishingly potent tool when put into the hands of a sufficiently skilled coder. It is a programming language that was built to handle the widest array of tasks possible. As such, it positively bursts with all forms and matter of far-out features — some of which can be exotic and even a tad outlandish, but all of which exist to serve a purpose.
While some people denounce it as convoluted and hopelessly byzantine on account of this fact, others swear by its handiness.
C++ is a programming language that brings together the powers of divergent programming paradigms — procedural, object-oriented, and generic — for maximal effect. It is a language that employs compilers to bring itself closer to the soul of a machine and thus supercharge its performance. It is a language that is far from a breeze to learn but which can bountifully repay those dedicated enough to master it.
Below, we will dive into the details of C++. And while the information presented here won’t enable you to code in the language, it will comprehensively acquaint you with all of the salient facts that you should know about it.
C++: An Exact Definition
C++ is a general-purpose, compiled, and case-sensitive programming language that was created to serve as an extension of the language C. Like C, C++ can serve as a procedural programming language, but it moves beyond C by offering features of the object-oriented and generic programming paradigms, as well as the ability to carry out some low-level memory manipulation.
How Does C++ Work?
To truly explain how C++ can be so powerful and so versatile, how it can do all of the extraordinarily varied work that it does, we must pause to explain and define some critical programming terminology referred to in the definition provided above. With these important concepts established and elucidated, we will then be able to combine them to create a broad but enlightening picture of the language’s functionality.
A Union of Programming Paradigms: Procedural, Object-Oriented, and Generic
The term “general purpose” simply means that it’s possible to write C++ code to make a computer do virtually anything. No important programming functionality is beyond the reach of this language. Indeed, it even offers a great many peculiar and exotic features that are not commonly in use at all but which nevertheless remain at programmers’ disposal. This is because the language’s creation was guided by a pragmatic and eclectic philosophy: So long as something could be used to handle a practical problem, the language’s creator, Bjarne Stroustrup, worked to include it.
How is C++ able to have such ecumenical powers? To answer this question, we must delve into the subject of the various programming paradigms.
Computer programming can be broken down into a series of more-or-less discrete paradigms, which dictate how code written under the aegis of each particular paradigm is structured. The particular paradigm or paradigms employed also have consequences for how suitable the programs built under their auspices are for solving particular classes of problems.
We need not discuss every paradigm and its intricacies here. Only three paradigms need to concern us because they are the three that C++ combines: procedural programming, object-oriented programming, and generic programming.
Procedural programming is the style that perhaps best approaches the intuitive idea that an untrained person has of what a computer program is and what it looks like. Broadly speaking, every computer program has two components: its data, which are the things that the program manipulates and works with, and its algorithm, which is the set of instructions according to which the program operates. Procedural programming privileges the algorithm side of this divide — that is to say, procedural programs are built with the thought that a program must carry out a certain set of instructions, and then those instructions are written into the program, usually indirect, sequential order. In general, procedural programs all consist of a series of actions to be performed, called functions, and a set of types of data called arguments, which are passed to those functions.
Object-oriented programming, by contrast, reverses this orientation. Unlike procedural programming, OOP privileges data. Every programmer employing OOP principles aims to construct forms of data that correspond to the essential features of whatever problem he is attempting to solve. His program will thus be tailor-made for that problem or for problems that are broadly similar to it, and will therefore be able to solve it simply and naturally.
Certain technical terms are associated with OOP, which we will briefly define here. A class is a set of instructions for the creation of a particular sort of data. An object is a particular data structure that has been built according to the instructions specified in some class. A method is an action to be performed within the particular context of some class — that is, it’s the OOP equivalent of a function but localized to a given class.
Four other special terms are essential to an understanding of OOP:
Encapsulation refers to the fact that in an OOP program, each class is a self-contained whole. The code in each class is hermetically sealed off from the code in other classes.
Abstraction refers to the idea of only showing certain important details in your code while hiding everything else and letting it work in the background. Certain bits of code may perform high-level functions, while other code, which is closer to the guts of the machine, may do other things. Considering both levels at once can generate enormous and unnecessary complexity, while separating these levels not only simplifies programs but also allows them to be more portable and less impacted by the change.
Inheritance is the idea that classes should be organized in hierarchies and that more specific lower-level classes can inherit the properties of the more general higher-level classes. Higher-level classes are called parent classes, while lower-level classes are called child classes. When classes can inherit features from other classes, the amount of code that programmers need to write is greatly reduced.
Polymorphism refers to the ability of child classes to override the features of their parent classes when necessary. Thus, a particular piece of data or other feature can be either inherited or not, as needed.
As should be clear, working according to these principles makes it much easier to write programs that can carry out intricate tasks with many interlocking steps. It also streamlines coding and helps to improve program efficiency. These are things that C++ is known to do especially well.
Lastly, we must discuss the generic programming paradigm. Like OOP, this paradigm makes heavy use of abstraction. Like procedural programming, it privileges the algorithm side of every program. All programs make use of different data types — strings, integers, floating-point numbers, lists, arrays, etc. These types are often incompatible with one another, making it impossible for the same function to act on them without generating an error. But it is often useful to be able to do the same things to different data types. Generic programming allows you to do this without having to rewrite your functions for each data type.
Functions made under this paradigm are data-type independent. Like in OOP, programs written in this style are highly portable. Unlike in OOP, however, they are usually only suitable for small and specialized tasks.
In a word, C++ offers you the features and advantages of all of these approaches. Where one paradigm suffers from drawbacks, the others can be used to relieve the burden, allowing you to balance the pros and cons.
The next critical fact about C++ is that it is a compiled language. This means that all code written in it is run through a special program called a compiler which translates it into some other type of code — in this case, into assembly language. Assembly language is the code that is directly executed by a CPU. It is written in zeros and ones. Because it runs directly on the CPU, your machine will not have to perform any further translation on it. The upshot of this is that programs written in C++ can run with great speed. This is, therefore, one of the languages of all performance junkies in the coding world.
How Does One Write Programs in C++, and How Do They Work?
As with any other programming language, writing programs in C++ requires you to be familiar with its syntax. Anyone interested in learning to code in C++ can consult reference works like Stephen Prata’s C++ Primer Plus or any of a large number of video tutorials dedicated to teaching people the language, like this one, this one, and this one. Without diving too deeply into the weeds, however, a general discussion of how C++ programs run and a short description of the logic and syntax of a simple program can help you to get a handle on how the language works.
The first task for any programmer working in C++ is to write his program in a text editor of some sort and save it as a file with the appropriate extension. Once that’s finished, the compiler needs to get to work on the source code, translating it from the high-level, portable, abstract language in which it was written into the lower-level object code used by the machine on which the program must run. As mentioned above, the compiler will vary depending on the kind of computer on which the program is meant to run. Then, programmers must link their object code to some generic startup code as well as to whatever additional functions are required to make everything run properly. These additional functions are to be pulled from the appropriate C++ libraries.
Once these things are all properly linked together, the result will be a file containing your executable code. This is the code that runs on your machine.
Analyzing “Hello, World.”
For a small taste of what a program looks like, consider the following:
// C++ program to print “Hello, World”
// Header file for input/output functions
using namespace std;
// Main() function: the principal part of the program
// prints hello world
cout << “Hello, World”;
This is C++’s version of the “Hello World” program, a standard program that is always taught to beginners. Let’s break it down into pieces and see how it works.
In C++, anything written on a line following “//” is a comment. These are disregarded by the compiler and are only written to make it easier for humans to understand what is going on in the code. As the comments describe, this piece of code instructs the computer to print the phrase, “Hello, World.”
The main body of this program is the function main(). Every C++ program has such a main function, though the way that it may be organized varies wildly across different programs. In this simple case, the function has no arguments — that is, it does not take any values from any previous functions that may have called it. This is indicated by the fact that there is nothing in the parentheses in main(). We should pause to note that because main() is typically the focal point of any program, it is highly unusual for other functions within that program to call it. Rather, main() is typically called by the startup code that gets attached to your program after it has been run through a compiler.
int refers to the data type that main() returns to the function that calls it — in this case, an integer.
Everything located in the braces constitutes the body of the main function. It contains the statements that the function executes. Each statement in C++ must end in a semicolon. Cout refers to an object which can display various things on a computer screen. In this case, we are concerned with displaying the string, “Hello, World.” “<<” indicates that that string is to be passed to the cout object. return refers to the value that the main function is to return, though in this case, the integer 0 is simply a stand-in for an empty value. Thus, return 0 simply terminates the function.
A detailed discussion of the purpose that the lines “#include <iostream>” and “using namespace std;” serve within the logic of C++ programs is far beyond the scope of this article. In brief, however, these lines enable the program to use C++’s standard input/output capabilities and thus allow it to communicate with the outside world. They run your code through a preprocessor which modifies it in certain ways before the main work of compilation takes place. The line #include <iostream> uses the #include directive to locate the iostream file and append it to your code. This file contains several definitions that are essential to every program’s input/output schema. The line using namespace std; employs the using directive to go into a namespace called std, which is C++’s standard namespace. A namespace is a prepackaged unit of functions, classes, objects, and other components of a C++ compiler. If your program has to use pre-existing components with the same names, dividing these components into appropriate namespaces prevents the compiler from confusing them.
The above program is a very simple one, and our discussion of it has been rather cursory. Nevertheless, what has been said should be enough to acquaint you with some of C++’s basic syntax, some key statements and their meanings, and how the various parts of a program written in this language fit together.
The Origins and History of C++
A Little Pre-history
To fully understand C++’s history and appreciate its role in the evolution and development of computer programming, we have to go back quite a few years before the language itself was even created. Doing this will provide us with the facts necessary to place it in the proper context, to see what challenges the language’s creator was responding to, how the language dealt with those challenges, and why the language remains so powerful and so popular decades after its appearance on the world stage.
As already mentioned above, computer programming can be broken down into a few basic paradigms, paradigms which, broadly speaking, revolve around the question of whether data or algorithms are to be privileged in the organization of computer code. Up until the late 1960s, all existing programming languages fell into the procedural paradigm. While Simula has undeniable historical significance as the first-ever object-oriented programming language, and while Xerox’s Smalltalk pushed the envelope a bit further in the 1970s by using OOP principles to create a functioning graphical user interface, the lion’s share of programming languages before the 1980s was procedural.
As computer hardware advanced and acquired the capability to run longer and more intricate programs, programmers naturally began obliging their hardware and writing these more intricate programs. As this process accelerated, however, the inherent weaknesses of the procedural approach began rearing themselves in some rather messy and unfortunate ways. All programs need to specify ways to route data to other sets of instructions for further processing. In procedural languages like BASIC and FORTRAN, this is done with branching statements. Unfortunately, as programs grow larger, the number of branching statements that they need, as well as the interactions between the branching statements and the special exceptions and other rules under which they operate, grow vastly more complex. Before long, programs written in this style began turning into unwieldily monstrosities, and it became an enormous challenge for humans to reliably read, modify or debug them.
In the early 1970s, Dennis Ritchie, a computer scientist working at Bell Labs, ran straight into the wall that had been thrown up by these issues as he labored on a project to expand the capabilities of the Unix Operating System. He also had further challenges to contend with. Since a machine’s operating system is so intimately connected to its hardware, any attempts to modify the operating system must be done in a language that can control hardware directly. Ritchie also preferred to use a language that was concise and in which compact programs could be written that ran at a high rate of speed. The traditional response to these challenges had at that time been to write the code in assembly language. That solution, however, was unacceptable to Ritchie because assembly language was an extremely low-level language, meaning that it was specific to each particular processor. This severely compromised portability, and portability was precisely one of the things that Ritchie wanted because Unix was meant to run on many different kinds of computers.
In response to this array of issues, Ritchie decided to create C, the direct predecessor of C++. C is a procedural language, but it implements something called structured programming, which attempts to control branching by reducing that behavior to a small set of well-defined constructs, like the for loop, the while loop, or the if-else statement. These have since become standard parts of many different programming languages. Structured programming also breaks programs down in a top-down way by reducing them to a series of relatively self-contained functions. Moreover, because C is a compiled language, it was successfully able to combine low-level speed, performance, and hardware access with high-level portability.
Though structured, it did serve to mitigate the grotesque and cumbersome complexity of some programs, but it ultimately proved to be but a temporary stop-gap measure. To truly resolve this issue, it was becoming clear that a shift away from the procedural paradigm was necessary.
C++ was originally unveiled to the world in 1985 as the brainchild of Bjarne Stroustrup, another computer scientist who worked at Bell Labs. Having worked on the language since the early 1980s, Stroustrup’s goal from the beginning was to be as non-ideological as possible, to emphasize practical utility and the ability to solve a diverse array of problems over any kind of pre-decided theoretical structure or purity.
This is evident when one makes note of certain basic facts about the language, like the fact that it was not constructed according to any single programming paradigm but, in fact, straddles multiple paradigms. Because C++ is a superset of C, any program that is valid in C — with only a few very minor exceptions — is also automatically valid in C++, though, of course, the converse does not hold. This immediately incorporates the procedural paradigm into the latter language. C++’s initial distinctive feature was its ability to make use of classes, objects, and other OOP concepts, thus solving the problem of large, unwieldy, unreadable programs by reorienting the very way in which programs are built. Here, Stroustrup was inspired by Simula, the original object-oriented programming language.
As C++ began to grow in popularity, Stroustrup equipped it with the ability to partake of the advantages of the generic programming paradigm as well. Furthermore, he and others gradually equipped it with a wide collection of libraries that offered programmers proven, pre-established solutions for many problems. Thus, the result was a language that was highly general and portable, extremely efficient, and highly versatile.
As with all new and evolving programming languages, C++ did not initially have any uniform standards, but as it matured, it inevitably congealed into fixed forms. The language needed to be standardized because any discrepancies — quite apart from any issues raised by submitting programs to different compilers — meant that programs could not be interoperable between machines.
The first serious attempt to do this occurred in 1990 when the American National Standards Institute (ANSI) and the International Organization for Standardization (ISO) met in joint committees to hammer out the issues. In 1995 and 1996, they would meet again on multiple occasions, submitting further standardization proposals for public comment. By now, they had also incorporated things like exceptions, templates (for generic programming), runtime type identification, and the Standard Template Library.
In 1998, joined by the International Electrotechnical Commission (IEC), these groups produced the first C++ standard. These were later refined and updated in 2003, 2011, 2014, 2017, and 2020.
How is C++ Used in the Real World?
The foregoing discussion of C++ has been rather abstract and general. Though this is unavoidable if one wishes to provide readers with a general overview of the language’s features and nature, it may leave many hungry to know what tangible things one can use C++ to do. As mentioned earlier, C++ was created with a utilitarian philosophy that emphasized practical results and capabilities above all else, so no one should be fooled into thinking that our discussion of classes, functions, compilers, objects and other concepts has no real-world applicability.
C++ is a programming language, and programming is basically about providing computers with instructions to do things. Given how much of our world is run by, powered, and made possible by computers, it should be obvious from this alone that C++ should have an enormous number of applications to things in the real world.
Virtually every piece of advanced technical or computerized equipment that you can imagine either, in fact, does make use of C++ or, given the language’s portability and broad capabilities, at least could do so.
Some Examples Where C++ Has Been Used
Here are a few areas where C++ has been used in the real world to achieve some extraordinary things. Be aware that this list is far from exhaustive:
- Video games
- Flight software
- Scientific research
- The financial sector
Because C++ programs typically run with such high speed, they are a natural option for gaming, and game designers who are committed to creating high-performance games turn to it frequently. World of Warcraft was coded in C++, as was the Unreal Engine behind games like Unreal Tournament. StarCraft, Counter-Strike, and countless other games for both PC and popular consoles were built with this language.
Defense contractors make copious use of C++ to model, test, and simulate the flight capabilities of military aircraft like F-16s and F-35s. Commercial planes, of course, need such software as well, as commercial pilots frequently train using flight simulators. Aircraft safety and performance software, which does things like optimizing wing design to minimize drag, also uses this language. The exacting standards of aircraft safety software make it a particularly attractive choice with which to build programs.
Cutting-edge scientific endeavors like space exploration and particle physics would not be what they are without C++. CERN scientists use programs written in that language to analyze and parse the data that emerge from experiments using particle accelerators. NASA also uses programs written in that language to equip its Mars Rovers with autonomous driving capabilities.
The Financial Sector
Major financial have C++ code running behind the scenes to keep them afloat. Whether we’re talking about hedge funds that use high-frequency trading algorithms that are coded in the language, credit card companies that use it to efficiently process large volumes of transactions or banks that use it to design their cryptographic security systems, C++ is everywhere in the financial sector.
Even Google uses C++. The language’s great power is what gives the Google search engine its power to quickly display search results, index, organize and efficiently crawl overall data, and create machine learning tools to further maximize performance.
The image featured at the top of this post is ©Maria Vonotna/Shutterstock.com.