C++ Programming/Print version
From Wikibooks, the open-content textbooks collection
About the book
Foreword
- Guide to Readers
The book is organized into different parts, but as this is a work that is always evolving, things may be missing or just not where they should be, you are free to become a writer and contribute to fix things up...
If you are already familiar with programming in other languages you can skip most of the Getting Started Chapter (it deals with basic and general programming concepts). You should not skip the Programming Paradigms introduction, since C++ does have some particulars on that topic that should be useful even if you already know an OOP language. The Language Comparisons Section, providing comparisons for the language(s) you already know, is important for veterans. However if this is your first contact with programming then continue on reading, and take in consideration that the Programming Paradigms section can be hard to digest if you lack some bases, don't despair, the relevant points will be extended when other concepts are introduced, that section is provided to give you a mental framework to help you not only to understand C++, but to let you easily adapt to (and from) other languages that share those concepts.
Authors
- The following people are authors to this book
- Panic
There are many other contributors/editors to the book; a verifiable list of all contributions exist as History Logs at Wikibooks (http://en.wikibooks.org/).
- Acknowledgment is given for using some contents from other works like Programming C-/- -/-, Wikipedia, the Wikibooks Java Programming and C Programming, C++ Exercises for beginners, C/C++ Reference Web Site, and from Wikisource as from authors such as Scott Wheeler, Stephen Ferg and Ivor Horton.
| Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License." |
Getting Started
Introducing C++
C++ (pronounced "see plus plus") is a general-purpose, object-oriented, statically typed, free-form, multi-paradigm programming language supporting procedural programming, data abstraction, and generic programming. During the 1990s, C++ became one of the most popular computer programming languages.
History
Bjarne Stroustrup from Bell Labs was the designer and original implementer of C++ (originally named "C with Classes") during the 1980s as an enhancement to the C programming language. Enhancements started with the addition of classes, followed by, among many features, virtual functions, operator overloading, multiple inheritance, templates, and exception handling, these and other features are covered in detail along this book.
The C++ programming language is a standard recognized by the the ANSI (The American National Standards Institute), BSI (The British Standards Institute), DIN (The German national standards organization), several other national standards bodies, and was ratified in 1998 by the ISO (The International Standards Organization) as ISO/IEC 14882:1998, the current version of which is the 2003 version, ISO/IEC 14882:2003.
The 1998 C++ Standard consists of two parts: the Core Language and the Standard Library; the latter includes the Standard Template Library and the Standard C Library (ANSI C 89). Many C++ libraries exist which are not part of the Standard, such as Boost. Also, non-Standard libraries written in C can generally be used by C++ programs.
Features introduced in C++ include declarations as statements, function-like casts, new/delete, bool, reference types, const, inline functions, default arguments, function overloading, namespaces, classes (including all class-related features such as inheritance, member functions, virtual functions, abstract classes, and constructors), operator overloading, templates, the :: operator, exception handling, run-time type identification, and more type checking in several cases. Comments starting with two slashes ("//") were originally part of BCPL, and was reintroduced in C++. Several features of C++ were later adopted by C, including const, inline, declarations in for loops, and C++-style comments (using the // symbol).
- C++ source code example
// 'Hello World!' program #include <iostream> int main() { std::cout << "Hello World!" << std::endl; return 0; }
Traditionally the first program people write in a new language is called "Hello, World." because all it does is print the words Hello World. Hello World Explained offers a detailed explanation of this code; the included source code is to give you an idea of a simple C++ program.
Overview
Before you begin your journey to understand how to write programs using C++, it is important to understand a few key concepts that you may encounter. These concepts, while not unique to C++, help in understanding programming in general. Readers who have experience in another programming language may wish to skim through or skip this section entirely.
There are many different kinds of programs in use today. From the operating system you use that makes sure everything works as it should, to the video games and music applications you use for fun, programs can fulfill many different purposes. What all programs (also called software or applications) have in common is that they all are made up of a sequence of instructions written in some form of programming language. These instructions tell a computer what to do, and generally how to do it. Programs can contain anything from instructions to solve math problems or send emails, to how to behave when a video game character is shot in a game. The computer will follow the instructions of a program one instruction at a time from start to finish.
Why learn C++?
Why not? This is the most clarifying approach to the decission to learn anything, learning is always good, selecting what to learn is more important as is how to prioritize tasks. Another side of this problem is that you will be investing some time in getting a new skill set, you have to consider in what ways will this benefit you. Check your objectives and compare similar projects or see what the programming market is in need. In any case the more programming languages you know, the better.
If you are approaching the learning process only to add another notch under your belt, that is, willing only to dedicate enough effort to understand its major quirks and learn something about its dark corners then you should be best served in learning first two other languages, this will clarify what makes C++ special in its approach to programming problems. You should select one imperative language and in this C will probably have a better market value and will have a direct relation to C++ (a good substitute would be ASM) and the second language should be an Object Oriented language like Java for the same reasons, as there is a close relation between the tree languages.
If you are willing to dedicate a more than passing interest in C++ then you can even learn C++ as your first language but dedicate some time understanding the different paradigms and why C++ is a multi-paradigm language or how some like to call it a hybrid language.
Learning C is not a requirement for understanding C++, but knowing how to use an imperative language is, C++ will not make it easy for you to understand and distinguish some of this deeper concepts, since in C++ you are free to implement solutions with a great range of freedom. Understanding what options to make will become the cornerstone of mastering the language.
You should not learn C++ if you are only interested in applying or learning about Object Oriented programing since the nomenclature used and some of the approaches C++ takes to the problem will probably increase the difficulty level in learning and mastering those concepts, if you are truly interested in Object Oriented programming, the best language for that is Smalltalk.
As with all languages C++ has a specific scope of application, were it can truly shine, and if we take a quick comparison with the previous mentioned languages, C++ is harder to learn than C and Java but more powerful than both. C++ enables you to abstract from the little things you have to deal with in C but will grant you a bigger control and responsibility than Java and will also not provide the default features you can obtain in similar higher level languages. You will have to search and examine several external implementations of these features and freely select those that best serve your purposes or you may even have to implement your own solution.
What is a Programming Language?
In the most basic terms, a "programming language" is a means of communication between a human being (programmer) and a computer. A programmer uses this means of communication in order to give the computer instructions. These instructions are called "programs".
Like the many languages we use to communicate with each other, there are many languages that a programmer can use to communicate with a computer. Each language has its own set of words and rules, called semantics. If you're going to write a program, you have to follow the semantics of the language you're writing in, or you won't be understood.
Programming languages can basically be divided in to two categories: Low-Level and High-level, next we will introduce you to these concepts and their relevance to C++.
Low-level Languages
There are two general types of low level "languages".
Machine code (also called binary) is the lowest form of a low-level language. Machine code consists of a string of 0s and 1s, which combine to form meaningful instructions that computers can take action on. If you look at a page of binary it becomes apparent why binary is never a practical choice for writing programs; what kind of person would actually be able to remember what a bunch of strings of 1 and 0 mean ?
Assembly language (also called ASM), is just above machine code on the scale from low level to high level. It is a human-readable translation of the machine language instructions the computer executes. For example, instead of referring to processor instructions by their binary representation (0s and 1s), the programmer refers to those instructions using a more memorable (mnemonic) form. These mnemonics are usually short collections of letters that symbolize the action of the respective instruction, such as "ADD" for addition, and "MOV" for moving values from one place to another.
|
NOTE: |
You do not have to understand assembly language to program in C++, but it does help to have an idea of what's going on "behind-the-scenes". Learning about assembly language will also allow you to have more control as a programmer and help you in debugging and understanding code.
High-level Languages
Higher level languages partially solve the problem of abstraction to the hardware (CPU, co-processors, number of registers etc...) by providing portability of code. High-level languages do more with less code, although there is sometimes a loss in performance and less freedom for the programmer. They also attempt to use English language words in a form which can be read and generally interpreted by the average person with little experience in them. A program written in one of these languages is sometimes referred to as "human-readable code". In general, more abstraction makes it easier for a language be learned. No programming language is written in what one might call "plain English" though, (although BASIC comes close.) Because of this, the text of a program is sometimes referred to as "code", or more specifically as "source code." This is discussed in more detail in the C++ Programming Code Section of the book.
Keep in mind that this classification scheme is evolving. C++ is still considered a high-level language, but with the appearance of newer languages (Java, C#, Ruby etc...), C++ is beginning to be grouped with lower level languages like C.
Translating Programming Languages
Since a computer is only capable of understanding machine code, human-readable code must be either interpreted or translated into machine code.
An interpreter is a program (often written in a lower level language) that interprets the instructions of a program one instruction at a time into commands that are to be carried out by the interpreter as it happens. Typically each instruction consists of one line of text or provides some other clear means of telling each instruction apart and the program must be reinterpreted again each time the program is run.
A compiler is a program that translates the instruction of a program one instruction at a time into machine code. The translation into machine code may involve splitting one instruction understood by the compiler into multiple machine instructions. The instructions are only translated once and after that the machine can understand and follow the instructions directly whenever it is instructed to do so. A complete examination is given on the C++ Programming Compiler Section of the book.
The words and statements used to instruct the computer may differ, but no matter what words and statements are used, just about every programming language will include statements that will accomplish the following:
- Input
- Input is the act of getting information from a device such as a keyboard or mouse, or sometimes another program.
- Output
- Output is the opposite of input; it gives information to the computer monitor or another device or program.
- Math/Algorithm
- All computer processors (the brain of the computer), have the ability to perform basic mathematical computation, and every programming language has some way of telling it to do so.
- Testing
- Testing involves telling the computer to check for a certain condition and to do something when that condition is true or false. Conditionals are one of the most important concepts in programming, and all languages have some method of testing conditions.
- Repetition
- Perform some action repeatedly, usually with some variation.
An further examination is provided on the C++ Programming Statements Section of the book.
Believe it or not, that's pretty much all there is to it. Every program you've ever used, no matter how complicated, is made up of functions that look more or less like these. Thus, one way to describe programming is the process of breaking a large, complex task up into smaller and smaller subtasks until eventually the subtasks are simple enough to be performed with one of these simple functions.
C++ is mostly compiled rather than interpreted (there are some C++ interpreters), and then "executed" later. As complicated as this may seem, later you will see how easy it really is.
So as we have seen in the Introducing C++ Section, C++ evolved from C by adding some levels of abstraction (so we can correctly state that C++ is of a higher level than C). We will learn the particulars of those differences in the Programming Paradigms Section of the book and for some of you that already know some other languages should look into Programming Languages Comparisons Section.
Programming Paradigms
A programming paradigm is a style or model of programming that affects the way programmers can design, organize and write programs. A multiparadigm programming language allows programmers to choose from a number of different programming paradigms. C++ is a multiparadigm programming language.
Procedural Programming
Procedural programming is a programming paradigm based upon the idea of a procedure call. Procedure calls are modular and are bound by scope. A procedural program is composed of one or more modules. Each module is composed of one or more subprograms. Modules may consist of procedures, functions, subroutines or methods, depending on the programming language. Procedural programs may possibly have multiple levels or scopes, with subprograms defined inside other subprograms. Each scope can contain names which cannot be seen in outer scopes.
Procedural programming offers many benefits over simple sequential programming since procedural code:
- is easier to read and more maintainable
- is more flexible
- facilitates the practice of good program design
- allows modules to be reused in the form of code libraries.
Object-Oriented Programming
Object-oriented programming can be seen as an extension of procedural programming in which programs are made up of collection of individual units called objects that have a distinct purpose and function with limited or no dependencies on implementation. For example, a car is like an object; it gets you from point A to point B with no need to know what type of engine the car uses or how the engine works. Object-oriented languages usually provide a means of documenting what an object can and cannot do, like instructions for driving a car.
Objects and Classes
An object is composed of members and methods. The members (also called data members, characteristics, attributes, or properties) describe the object. The methods generally describe the actions associated with a particular object. Think of an object as a noun, its members as adjectives describing that noun, and its methods as the verbs that can be performed by or on that noun.
For example, a sports car is an object. Some of its members might be its height, weight, acceleration, and speed. An object's members just hold data about that object. Some of the methods of the sports car could be "drive", "park", "race", etc. The methods really don't mean much unless associated with the sports car, and the same goes for the members.
The blueprint that lets us build our sports car object is called a class. A class doesn't tell us how fast our sports car goes, or what color it is, but it does tell us that our sports car will have a member representing speed and color, and that they will be say, a number and a word (or hex color code), respectively. The class also lays out the methods for us, telling the car how to park and drive, but these methods can't take any action with just the blueprint - they need an object to have an effect.
Inheritance
This concept describes a relationship between two (or more) types, or classes, of objects in which one is said to be a "subtype" or "child" of the other, as result the "child" object is said to inherit features of the parent, allowing for shared functionality, this lets programmers re-use or reduce code and simplifies the development and maintenance of software.
Inheritance is also commonly held to include subtyping, whereby one type of object is defined to be a more specialized version of another type (see Liskov substitution principle), though non subtyping inheritance is also possible.
Inheritance is typically expressed by describing classes of objects arranged in an inheritance hierarchy reflecting common behavior.
For example, one might create a variable class "Mammal" with features such as eating, reproducing, etc.; then define a subtype "Cat" that inherits those features without having to explicitly program them, while adding new features like "chasing mice". This allows commonalities among different kinds of objects to be expressed once and reused multiple times.
In C++ we can then have classes which are related to other classes (a class can be defined by means of an older, pre-existing, class ). This leads to a situation in which a new class has all the functionality of the older class, and additionally introduces its own specific functionality. Instead of composition, where a given class contains another class, we mean here derivation, where a given class is another class.
This OOP property will be explained further when we talk about Classes (and Structures) inheritance in the Classes Inheritance Section of the book.
If one wants to use more than one totally orthogonal hierarchy simultaneously, such as allowing "Cat" to inherit from "Cartoon character" and "Pet" as well as "Mammal" we are using multiple inheritance.
Multiple Inheritance
Multiple inheritance is the process by which one class can inherit the properties of two or more classes (variously known as its base classes, or parent classes, or ancestor classes, or super classes).
In some similar language, multiple inheritance is restricted in various ways to keep the language simple, such as by allowing inheritance from only one real class and a number of "interfaces", or by completely disallowing multiple inheritance. C++ places the full power of multiple inheritance in the hands of programmers, but it is needed only rarely, and (as with most techniques) can complicate code if used inappropriately. Because of C++'s approach to multiple inheritance, C++ has no need of separate language facilities for "interfaces"; C++'s classes can do everything that interfaces do in some related languages.
Polymorphism
Polymorphism allows a single name to be reused for several related but different purposes. The purpose of polymorphism is to allow one name to be used for a general class. Depending on the type of data, a specific instance of the general case is executed.
The concept of polymorphism is wider. Polymorphism exists every time we use two functions that have the same name, but differ in the implementation. They may also differ in their interface, e.g., by taking different arguments. In that case the choice of which function to make is via overload resolution, and is performed at compile time, so we refer to static polymorphism.
Dynamic polymorphism will be covered deeply in the Classes Section where we will address its use on redefining the method in the derived class.
Generic Programming
Generic programming or polymorphism is a programming style that emphasizes techniques that allow one value to take on different types as long as certain contracts such as subtypes and signature are kept. In simpler term generic programming is based in finding the most abstract representations of efficient algorithms. Templates popularized the notion of generics. Templates allow code to be written without consideration of the type with which it will eventually be used. Templates are defined in the Standard Template Library (STL), were generic programming was introduced into C++.
Statically Typed
Typing refers to how a computer language handles its variables. As we will see in depth later, variables are values that the program uses during execution. These values can change; they are variable, hence their name. Static typing usually results in compiled code optimizations. Since the compiler knows the exact types that are in use, it can produce machine code that is optimized for a limited set of types. In C++, variables need to be defined before they are used so that compilers know what type they are.
Static typing usually finds type errors more reliably at compile time, increasing the reliability of compiled programs. Simply put, it means that "A round peg won't fit in a square hole", so the compiler will report an error when a type leads to ambiguity or incompatible usage. However, programmers disagree over how common type errors are and what proportion of bugs that are written would be caught by static typing. Static typing advocates believe programs are more reliable when they have been type checked, while dynamic typing advocates point to distributed code that has proved reliable.
A statically typed system constrains the use of powerful language constructs more than it constrains less powerful ones. This makes powerful constructs harder to use, and thus places the burden of choosing the "right tool for the problem" on the shoulders of the programmer, who might otherwise be inclined to use the most powerful tool available. Choosing overly powerful tools may cause additional performance, reliability or correctness problems, because there are theoretical limits on the properties that can be expected from powerful language constructs. For example, indiscriminate use of recursion or global variables may cause well-documented adverse effects.
Static typing allows construction of libraries which are less likely to be accidentally misused by their users. This can be used as an additional mechanism for communicating the intentions of the library developer.
Free-form
Free-form refers to how the programmer crafts the code. Basically, there are no rules on how you choose to write your program, save for the semantic rules of C++. Any C++ program should compile as long as it is legal C++.
The free-form nature of C++ is used (or abused, depending on your point of view) by some programmers in crafting obfuscated code, which is code that is purposefully written to be difficult to understand. However, complicated programming is also a security device, ensuring that the source code is harder to duplicate, short of using the whole program exactly how it was originally written.
Language Comparisons
There isn't a perfect language. It all depends on the tools and the objective. The optimal language (in terms of run-time performance) is machine code but machine code (binary) is the least efficient programming language in terms of coder time. The complexity of writing large systems is enormous with high-level languages, and beyond human capabilities with machine code. In the next section C++ will be compared with other closely related languages like C, Java, C# and C++/CLI.
The quote above is shown to indicate that no programming language at present can translate directly concepts or ideas into useful code, there are solutions that will help. We will cover the use of Computer-aided software engineering (CASE) tools that will address part of this problem but its use does require planing and some degree of complexity.
The intention of these sections is not to promote one language above another; each has its applicability. Some are better in specific tasks, some are simpler to learn, others only provide a better level of control to the programmer. This all may depend also on the level of control the programmer has of a given language.
Garbage Collection
In C++ garbage collection is optional rather than required. In the Garbage Collection Section of this book we will cover this issue deeply.
Why doesn't C++ include a finally keyword?
As we will see in the Resource Acquisition Is Initialization (RAII) Section of the book, RAII can be used to provide a better solution for most issues. When finally is used to clean up, it has to be written by the clients of a class each time that class is used (for example, clients of a File class have to do I/O in a try/catch/finally block so that they can guarantee that the File is closed). With RAII, the destructor of the File class can make that guarantee. Now the cleanup code has to be coded only once — in the destructor of File; the users of the class don't need to do anything.
Mixing Languages
C 89/99
C was essentially the core language of C++ when Bjarne Stroustrup, decided to create a "better C". Many of the syntax conventions and rules still hold true and so we can even state that C was a subset of C++, most recent C++ compilers will also compile C code taking into consideration the small incompatibilities, since C99 and C++ 2003 are not compatible any more. You can also check more information about the C language on the C Programming Wikibook ( http://en.wikibooks.org/wiki/C_Programming ).
C++ as defined by the ANSI standard in 98 (called C++98 at times) is very nearly, but not quite, a superset of the C language as it was defined by its first ANSI standard in 1989 (known as C89). There are a number of ways in which C++ is not a strict superset, in the sense that not all valid C89 programs are valid C++ programs, but the process of converting C code to valid C++ code is fairly trivial (avoiding reserved words, getting around the stricter C++ type checking with casts, declaring every called function, and so on).
In 1999, C was revised and many new features were added to it. As of 2004, most of these new "C99" features are not there in C++. Some (including Stroustrup himself) have argued that the changes brought about in C99 have a philosophy distinct from what C++98 adds to C89, and hence these C99 changes are directed towards increasing incompatibility between C and C++.
The merging of the languages seems a dead issue as coordinated actions by the C and C++ standards committees leading to a practical results didn't happen and it can be said that the languages started even to diverge.
Some of the differences are:
- C++ supports function overloading (absent in C89, allowed only for some standard library code in C99).
- C++ supports inheritance and polymorphism.
- C++ adds keyword class, but keeps struct from C, with compatible semantics.
- C++ supports access control for class members.
- C++ supports generic programming through the use of templates.
- C++ extends the C89 standard library with its own standard library.
- C++ and C99 offer different complex number facilities.
- C++ has bool and wchar_t as primitive types, while typedefs in C.
- C++ comparison operators return bool, while C returns int.
- C++ supports overloading of operators.
- C++ character constants have type char, while C character constants have type int.
- C++ has additional cast operators (static_cast, dynamic_cast, const_cast and reinterpret_cast).
- C++ adds mutable keyword to address the imperfect match between physical and logical constness.
- C++ extends the type system with references.
- C++ supports member functions, constructors and destructors for user-defined types to establish invariants and to manage resources.
- C++ supports runtime type identification (RTTI), via typeid and dynamic_cast.
- C++ includes exception handling.
- C++ has std::vector as part of its standard library instead of variable-length arrays as in C.
- C++ treats sizeof operator as compile time operation, while C allows it be a runtime operation.
- C++ has new and delete operators, while C uses malloc and free library functions exclusively.
- C++ supports object-oriented programming without extensions.
- C++ does not require use of macros and careful information-hiding and abstraction for code portability.
Java
This is a comparison of the Java programming language with the C++ programming language. C++ and Java share many common traits. You can get a better understanding of Java in the Java Programming WikiBook.
Java was created initially to support network computing on embedded systems. Java was designed to be extremely portable, secure, multi-threaded and distributed, none of which were design goals for C++. The syntax of Java was chosen to be familiar to C programmers, but direct compatibility with C was not maintained. Java also was specifically designed to be simpler than C++ but it keeps evolving above that simplification.
-
C++ Java backwards compatible with C backwards compatibility with previous versions execution efficiency developer productivity trusts the programmer restrains the programmer's abilities arbitrary memory access possible memory access only through objects concise expression explicit operation can arbitrarily override types type safety procedural or object-oriented object-oriented operator overloading meaning of operators immutable powerful capabilities of language feature-rich, easy to use standard library
Differences between C++ and Java are:
- C++ parsing is somewhat more complicated than with Java; for example,
Foo<1>(3);is a sequence of comparisons if Foo is a variable, but it creates an object if Foo is the name of a class template. - C++ allows namespace level constants, variables, and functions. All such Java declarations must be inside a class or interface.
constin C++ indicates data to be 'read-only,' and is applied to types.finalin java indicates that the variable is not to be reassigned. For basic types such asconst intvsfinal intthese are identical, but for complex classes, they are different.- C++ doesn't supports constructor delegation.
- C++ runs on the hardware, Java runs on a virtual machine so with C++ you have greater power at the cost of portability.
- C++, int main() is a function by itself, without a class.
- C++ access specification (public, private) is done with labels and in groups.
- C++ access to class members default to private, in Java it is protected.
- C++ classes declarations end in a semicolon.
- C++ lacks language level support for garbage collection while Java has built-in garbage collection to handle memory deallocation.
- C++ supports
gotostatements; Java does not, but its labeled break and labeled continue statements provide some structured goto-like functionality. In fact, Java enforces structured control flow, with the goal of code being easier to understand. - C++ provides some low-level features which Java lacks. In C++, pointers can be used to manipulate specific memory locations, a task necessary for writing low-level operating system components. Similarly, many C++ compilers support inline assembler. In Java, assembly code can still be accessed as libraries, through the Java Native Interface. However, there is significant overhead for each call.
- C++ allows a range of implicit conversions between native types, and also allows the programmer to define implicit conversions involving compound types. However, Java only permits widening conversions between native types to be implicit; any other conversions require explicit cast syntax.
- A consequence of this is that although loop conditions (
if,whileand the exit condition infor) in Java and C++ both expect a boolean expression, code such asif(a = 5)will cause a compile error in Java because there is no implicit narrowing conversion from int to boolean. This is handy if the code were a typo forif(a == 5), but the need for an explicit cast can add verbosity when statements such asif (x)are translated from Java to C++.
- A consequence of this is that although loop conditions (
- For passing parameters to functions, C++ supports both true pass-by-reference and pass-by-value. As in C, the programmer can simulate by-reference parameters with by-value parameters and indirection. In Java, all parameters are passed by value, but object (non-primitive) parameters are reference values, meaning indirection is built-in.
- Generally, Java built-in types are of a specified size and range; whereas C++ types have a variety of possible sizes, ranges and representations, which may even change between different versions of the same compiler, or be configurable via compiler switches.
- In particular, Java characters are 16-bit Unicode characters, and strings are composed of a sequence of such characters. C++ offers both narrow and wide characters, but the actual size of each is platform dependent, as is the character set used. Strings can be formed from either type.
- The rounding and precision of floating point values and operations in C++ is platform dependent. Java provides a strict floating-point model that guarantees consistent results across platforms, though normally a more lenient mode of operation is used to allow optimal floating-point performance.
- In C++, pointers can be manipulated directly as memory address values. Java does not have pointers—it only has object references and array references, neither of which allow direct access to memory addresses. In C++ one can construct pointers to pointers, while Java references only access objects.
- In C++ pointers can point to functions or member functions (function pointers or functors). The equivalent mechanism in Java uses object or interface references.
- C++ features programmer-defined operator overloading. The only overloaded operators in Java are the "
+" and "+=" operators, which concatenate strings as well as performing addition. - Java features standard API support for reflection and w:dynamic loading of arbitrary new code.
- Java has generics. C++ has templates.
- Both Java and C++ distinguish between native types (these are also known as "fundamental" or "built-in" types) and user-defined types (these are also known as "compound" types). In Java, native types have value semantics only, and compound types have reference semantics only. In C++ all types have value semantics, but a reference can be created to any object, which will allow the object to be manipulated via reference semantics.
- C++ supports multiple inheritance of arbitrary classes. Java supports multiple inheritance of types, but only single inheritance of implementation. In Java a class can derive from only one class, but a class can implement multiple interfaces.
- Java explicitly distinguishes between interfaces and classes. In C++ multiple inheritance and pure virtual functions makes it possible to define classes that function just as Java interfaces do.
- Java has both language and standard library support for multi-threading. The
synchronizedkeyword in Java provides simple and secure mutex locks to support multi-threaded applications. While mutex lock mechanisms are available through libraries in C++, the lack of language semantics makes writing thread safe code more difficult and error prone.
Memory management
- Java requires automatic garbage collection. Memory management in C++ is usually done by hand, or through smart pointers. The C++ standard permits garbage collection, but does not require it; garbage collection is rarely used in practice. When permitted to relocate objects, modern garbage collectors can improve overall application space and time efficiency over using explicit deallocation.
- C++ can allocate arbitrary blocks of memory. Java only allocates memory through object instantiation. (Note that in Java, the programmer can simulate allocation of arbitrary memory blocks by creating an array of bytes. Still, Java arrays are objects.)
- Java and C++ use different idioms for resource management. Java relies mainly on garbage collection, while C++ relies mainly on the RAII (Resource Acquisition Is Initialization) idiom. This is reflected in several differences between the two languages:
- In C++ it is common to allocate objects of compound types as local stack-bound variables which are destructed when they go out of scope. In Java compound types are always allocated on the heap and collected by the garbage collector (except in virtual machines that use escape analysis to convert heap allocations to stack allocations).
- C++ has destructors, while Java has finalizers. Both are invoked prior to an object's deallocation, but they differ significantly. A C++ object's destructor must be implicitly (in the case of stack-bound variables) or explicitly invoked to deallocate the object. The destructor executes synchronously at the point in the program at which the object is deallocated. Synchronous, coordinated uninitialization and deallocation in C++ thus satisfy the RAII idiom. In Java, object deallocation is implicitly handled by the garbage collector. A Java object's finalizer is invoked asynchronously some time after it has been accessed for the last time and before it is actually deallocated, which may never happen. Very few objects require finalizers; a finalizer is only required by objects that must guarantee some clean up of the object state prior to deallocation—typically releasing resources external to the JVM. In Java safe synchronous deallocation of resources is performed using the try/finally construct.
- In C++ it is possible to have a dangling pointer – a reference to an object that has been destructed; attempting to use a dangling pointer typically results in program failure. In Java, the garbage collector won't destruct a referenced object.
- In C++ it is possible to have an object that is allocated, but unreachable. An unreachable object is one that has no reachable references to it. An unreachable object cannot be destructed (deallocated), and results in a memory leak. By contrast, in Java an object will not be deallocated by the garbage collector until it becomes unreachable (by the user program). (Note: weak references are supported, which work with the Java garbage collector to allow for different strengths of reachability.) Garbage collection in Java prevents many memory leaks, but leaks are still possible under some circumstances.
Libraries
- C++ standard library only provides components that are relatively general purpose, such as strings, containers, and I/O streams. Java has a considerably larger standard library. This additional functionality is available for C++ by (often free) third party libraries, but third party libraries do not provide the same ubiquitous cross-platform functionality as standard libraries.
- C++ is mostly backward compatible with C, and C libraries (such as the APIs of most operating systems) are directly accessible from C++. In Java, the richer functionality of the standard library is that it provides cross-platform access to many features typically available in platform-specific libraries. Direct access from Java to native operating system and hardware functions requires the use of the Java Native Interface.
Runtime
- C++ is normally compiled directly to machine code which is then executed directly by the operating system. Java is normally compiled to byte-code which the Java virtual machine (JVM) then either interprets or JIT compiles to machine code and then executes.
- Due to the lack of constraints in the use of some C++ language features (e.g. unchecked array access, raw pointers), programming errors can lead to low-level buffer overflows, page faults, and segmentation faults. The Standard Template Library, however, provides higher-level abstractions (like vector, list and map) to help avoid such errors. In Java, such errors either simply cannot occur or are detected by the JVM and reported to the application in the form of an exception.
- In Java, w:bounds checking is implicitly performed for all array access operations. In C++, array access operations on native arrays are not bounds-checked, and bounds checking for random-access element access on standard library collections like std::vector and std::deque is optional.
Miscellaneous
- Java and C++ use different techniques for splitting up code in multiple source files. Java uses a package system that dictates the file name and path for all program definitions. In Java, the compiler imports the executable class files. C++ uses a header file source code inclusion system for sharing declarations between source files. (See Comparison of imports and includes.)
- Templates and macros in C++, including those in the standard library, can result in duplication of similar code after compilation. Second, dynamic linking with standard libraries eliminates binding the libraries at compile time.
- C++ compilation features a textual preprocessing phase, while Java does not. Java supports many optimizations that mitigate the need for a preprocessor, but some users add a preprocessing phase to their build process for better support of conditional compilation.
- In Java, arrays are container objects which you can inspect the length of at any time. In both languages, arrays have a fixed size. Further, C++ programmers often refer to an array only by a pointer to its first element, from which they cannot retrieve the array size. However, C++ and Java both provide container classes (std::vector and java.util.Vector respectively) which are resizable and store their size.
- Java's division and modulus operators are well defined to truncate to zero. C++ does not specify whether or not these operators truncate to zero or "truncate to -infinity". -3/2 will always be -1 in Java, but a C++ compiler may return either -1 or -2, depending on the platform. C99 defines division in the same fashion as Java. Both languages guarantee that
(a/b)*b + (a%b) == afor all a and b (b != 0). The C++ version will sometimes be faster, as it is allowed to pick whichever truncation mode is native to the processor. - The sizes of integer types is defined in Java (int is 32-bit, long is 64-bit), while in C++ the size of integers and pointers is compiler-dependent. Thus, carefully-written C++ code can take advantage of the 64-bit processor's capabilities while still functioning properly on 32-bit processors. However, C++ programs written without concern for a processor's word size may fail to function properly with some compilers. In contrast, Java's fixed integer sizes mean that programmers need not concern themselves with varying integer sizes, and programs will run exactly the same. This may incur a performance penalty since Java code cannot run using an arbitrary processor's word size.
Performance
Computing performance is a measure of resource consumption when a system of hardware and software performs a piece of computing work such as an algorithm or a transaction. Higher performance is defined to be 'using fewer resources'. Resources of interest include memory, bandwidth, persistent storage and CPU cycles. Because of the high availability of all but the latter on modern desktop and server systems, performance is colloquially taken to mean the least CPU cycles; which often converts directly into the least wall clock time. Comparing the performance of two software languages requires a fixed hardware platform and (often relative) measurements of two or more software subsystems. This section compares the relative computing performance of C++ and Java on common operating systems such as Windows and Linux.
Early versions of Java were significantly outperformed by statically compiled languages such as C++. This is because the program statements of these two closely related Level 6 languages may compile to a few machine instructions with C++, while compiling into several byte codes involving several machine instructions each when interpreted by a Java JVM. For example:
| Java/C++ statement | C++ generated code | Java generated byte code |
|---|---|---|
| vector[i]++; | mov edx,[ebp+4h] mov eax,[ebp+1Ch] |
aload_1 iload_2 |
While this may still be the case for embedded systems because of the requirement for a small footprint, advances in just in time (JIT) compiler technology for long-running server and desktop Java processes has closed the performance gap and in some cases given the performance advantage to Java. In effect, Java byte code is compiled into machine instructions at run time, in a similar manner to C++ static compilation, resulting in similar instruction sequences.
C++ is still faster in most operations than Java at the moment, even at low-level and numeric computation. For in-depth information you could check Performance of Java versus C++. It's a bit pro-Java but very detailed.
C#
C# (pronounced "See Sharp") is a multi-purpose computer programming language suitable for all development needs. There is a WikiBook (http://en.wikibooks.org/wiki/C_sharp) that introduces C# language fundamentals and covers a variety of the base class libraries (BCL) provided by the Microsoft .NET Framework.
C# is very similar to Java in that it takes the basic operators and style of C++ but forces programs to be type safe, in that it executes the code in a controlled sandbox called the virtual machine. As such, all code must be encapsulated inside an object, among other things. C# provides many additions to facilitate interaction with Microsoft's Windows, COM, and Visual Basic.
There are several shortcomings to C++ which are resolved in C#. One of the more subtle ones is the use of reference variables as function arguments. When a code maintainer is looking at C++ source code, if a called function is declared in a header somewhere, the immediate code does not provide any indication that an argument to a function is passed as a reference. An argument passed by reference could be changed after calling the function whereas an argument passed by value cannot be changed. A maintainer not be familiar with the function looking for the location of an unexpected value change of a variable would additionally need to examine the header file for the function in order to determine whether or not that function could have changed the value of the variable. C# insists that the ref keyword be placed in the function call (in addition to the function declaration), thereby cluing the maintainer in that the value could be changed by the function.
Managed C++ (C++/CLI)
Managed C++ is a shorthand notation for Managed Extensions for C++, which are part of the .NET framework from Microsoft. This extension of the C++ language was developed to add functionality like automatic garbage collection and heap management, automatic initialization of arrays, and support for multidimensional arrays, simplifying all those details of programming in C++ that would otherwise have to be done by the programmer.
Managed C++ is not compiled to machine code. Rather, it is compiled to Common Intermediate Language, which is an object-oriented machine language and was formerly known as MSIL
The Code
The task of programming, while not easy in its execution, is actually fairly simple in its goals. A programmer will envision, or be tasked with, a specific goal. Goals are usually provided in the form of "I want a program that will perform...fill in the blank..." The job of the programmer then is to come up with a "working model" (a model that may consist of one or more algorithms). That "working model" is sort of an idea of how a program will accomplish the goal set out for it. It gives a programmer an idea of what to write in order to turn the idea in to a working program. Once the programmer has an idea of the structure their program will need to take in order to accomplish the goal, they set about actually writing the program itself with all of the proper commands, functions and syntax. The code that they write is what actually implements the program, or causes it to perform the necessary task, and for that reason, it is sometimes called "implementation code".
How the instructions of a program are written out and stored is generally not a concept determined by a programming language. Punch cards used to be in common use, however under most modern operating systems the instructions are commonly saved as plain text files that can be edited with any text editor. These files are the source of the instructions that make up a program and so are sometimes referred to as source files but a more exclusive definition is source code.
When referring to source code or just source, you are considering only the files that contain code, the actual text that makes up the functions (actions) for computer to execute. By referring to source files you are extending the idea to not only the files with the instructions that make up the program but all the raw files resources that together can build the program.
- Source code
Source code is the halfway point between human language and machine code. As mentioned before, it can be read by people to an extent, but it can also be parsed (converted) into machine code by a computer. The machine code is the strings of 1's and 0's that the computer can fully understand and act on.
In a small program, you might have as little as a few dozen lines of code at the most, whereas in larger programs, this number might stretch into the thousands or even millions. For this reason, it is sometimes more practical to split large amounts of code across many files. This makes it easier to read, as you can do it bit by bit, and it also reduces compile time of each source file. It takes much less time to compile a lot of small source files than it does to compile a single massive source file.
Managing size is not the only reason to split code, though. Often, especially when a piece of software is being developed by a large team, source code is split. Instead of one massive file, the program is divided into separate files, and each individual file contains the code to perform one particular set of tasks for the overall program. This creates a condition known as Modularity. Modularity is a quality that allows source code to be changed, added to, or removed a piece at a time. This has the advantage of allowing many people to work on separate aspects of the same program, thereby allowing it to move faster and more smoothly. Source code for a large project should always be written with modularity in mind. Even when working with small or medium sized projects, it is good to get in the habit of writing code with ease of editing and use in mind.
C++ source code is case sensitive. This means that it distinguishes between lowercase and capital letters, so that it sees the words "hello," "Hello," and "HeLlO" as being totally different things. This is important to remember and understand, it why will be discussed further in the Coding Style Section.
File Organization
Most operating systems require C++ files to be designated by a specific extension. The most common extension for a C++ file is ".cpp" for implementation code (the code that the programmer wrote to perform a given task), and ".h" for declaration or "header" files (though ".hpp" is becoming increasingly popular). Header files are a complicated concept that will be discussed with more detail later, but in general terms a header file is a special kind of source code that traditionally appears at the beginning of a complete file. There are other common extensions such as, ".cc", ".C", ".cxx", and ".c++" for "implementation" code. For header files, the same extension variations are used, but the first letter of the extension is usually replaced with an "h" as in, ".hc", ".H", ".hxx", ".hpp" etc. Please note that file extensions don't include quotes; the quotes were added for clarity in this text. Regardless of what the specific form of the extension is, it serves one purpose: telling the Operating System, the IDE or the compiler that the text within the file is C++ source code, and not just random characters and so enable them to perform the necessary actions.
Some authors will refer to files with a .cpp extension as "source files" and files with the .h extension as "header files". However, both of those qualify as source code. As a convention for this book, all code, whether contained within a .cpp extension (where a programmer would put it), or within a .h extension (for headers), will be called source code. Any time we're talking about a .cpp file, we'll call it an "implementation file", and any time we're referring to a header file, we'll call it a "declaration file". You should check the editor/IDE or alter the configuration to a setup that best suits you and others that will read and use this files.
.cpp
.h
Object files
All other source files that are not or resulted from source code, the support data needed for the build (creation) of the program. The extensions of this files may vary from system to system, since they depend on the IDE/Compiler and necessities of the program, they may include graphic files, or raw data formats.
- Object code
The compiler produces machine code equivalent (object code) of the source code, contain the binary language (machine language) instruction to be used by the computer to do as was instructed in the source code, that can then be linked into the final program. This step ensures that the code is valid and will sequence into an executable program. Most object files have the file extension (.o) with the same restrictions explained above for the (.cpp/.h) files.
- Libraries
Libraries are commonly distributed in binary form, using the (.lib) extension and header (.h) that provided the interface for its utilization. Libraries can also be dynamically linked and in that case the extension may depend on the target OS, for instance windows libraries as a rule have the (.dll) extension, this will be covered later on in the book in the Libraries Section of this book.
Statements
Most programming languages have the concept of a statement. A statement is a command that the programmer gives to the computer. It is also sometimes referred as an expression.
Example
cout << "Hi there!"; // a single statement
A clear indicator that a line of code is a statement is its termination with an ending semicolon (;). Each statement performs an action. That statement and command will be examined in detail later on, for now consider only, it as a verb ("cout") and the other details as information (what to print). In this case, the command "cout" means "show on the screen," (not "print on the printer").
The programmer either enters the statement directly to the computer (by typing it while running a special program), or creates a text file with the command in it (you can use any text editor for that). You could create a file called "hi.txt", put the above command in it, and give the file to the computer.
If one were to write multiple statements, it is recommended that each statement be entered on a separate line and should end with a semicolon (;).
cout << "Hi there!"; // a statement cout << "Strange things are afoot..."; // another statement
However, there is no problem writing the code this way:
cout << "Hi there!"; cout << "Strange things are afoot...";
The former code gathers appeal in the developer circles. Writing statements as in the second example only makes your code look more complex and incomprehensible. We will speak of this deeply in the Coding Style Conventions Section of the book.
If you have more than one command in the file, each will be performed in order, top to bottom.
The computer will perform each of these commands sequentially. It's invaluable to be able to "play computer" when programming. Ask yourself, "If I were the computer, what would I do with these statements?" If you're not sure what the answer is, then you are very likely to write incorrect code. Stop and check the manual for the programming language you're using.
In the above case, the computer will look at the first statement, determine that it's a cout statement, look at what needs to be printed, and display that text on the computer screen. It'll look like this:
Hi there!
Note that the quotation marks aren't there. Their purpose in the program is to tell the computer where the text begins and ends, just like in English prose. The computer will then continue to the next statement, perform its command, and the screen will look like this:
Hi there! Strange things are afoot...
When the computer gets to the end of the text file, it stops. There are many different kinds of statements, depending on which programming language is being used. For example, there could be a beep statement that causes the computer to output a beep on its speaker, or a window statement that causes a new window to pop up.
Also, the way statements are written will vary depending on the programming language. These differences are fairly superficial. The set of rules like the first two is called a programming language's syntax. The set of verbs is called its library.
cout << "Hi there!";
- Statement Blocks
Also referred to Code Blocks (or in C++-speak, a compound statement), consist on one or more statements or commands that are contained between a pair of curly braces { }. Such a block of statement can be named or be provided a condition for execution. Below is how you'd place a series of statements in a block.
{ int a = 10; int b = 20; int result = a + b; }
A code block is Blocks are used primarily in loops, conditionals and functions. Blocks can be nested inside one another, for instance as an if structure inside of a loop inside of a function.
- Program Control Flow
As seen above the statements are evaluated in the order as they occur (sequentially). The execution of flow begins at the top most statement and proceed downwards till the last statement is encountered. A statement can be substituted by a statement block. There are special statements that can redirect the execution flow based on a condition, those statements are called branching statements, described in detail in the Control Flow Construct Statements Section of the book.
Coding Style Conventions
As seen earlier, indentation and the use of white spaces or tabs are completely ignored by the compiler. However, a style guide or code convention goes beyond that to give programmers a fixed structure or style on how they should format their code, name their variables, place their comments or any other non language dependent structural decision that is used on the code. This can be very important, as you share a project with others. Agreeing to a set of rules enables a common set of coding standards and recommendations that will enable a greater understandings and transparency of the code base, providing a common ground for undocumented structures, making for easy debugging, and will increase code maintainability. These rules can be referred to as Source Code Style.
A list of different approaches can be found on the Reference Section. The most commonly used style for the C++ (and C) language is the Kernighan and Ritchie (K&R) style-guide. You should be warned that this is one of the first decisions as you take on a project and in a democratic environment a consensus can be very hard to achieve, programmers tend to stick to a coding style, they have it automated and any deviation can be very hard to conform with, if you don't have a favorite style try to use the smallest possible variation to a common one or get as broad a view as you can get, so that you can adapt easily to changes or defend your approach. There is software that can help to format or beautify the code, but automation can have it's drawbacks.
- Standardization is Important
It does not matter which particular coding style you pick. However, once a coding style is selected, it should be kept throughout the same project. Reading code that follows different styles can become very difficult. In the next sections we try to explain why some of the options are common practice without forcing you to adopt a specific style.
Identifier Naming
To recall the definition for C++ Identifier:
|
This leaves a lot of freedom in naming. It is suggested that you also follow these rules:
Leading underscores
In most contexts, leading underscores are better avoided. They are reserved for the compiler or internal variables of a library, and can make your code less portable and more difficult to maintain. Those variables can also be stripped from a library (i.e. the variable isn't accessible anymore, it is hidden from external world) so unless you want to override an internal variable of a library, don't do it.
Reusing existing names
Do not use the names of standard library functions and objects for your identifiers as these names are considered reserved words and programs may become difficult to understand when used in unexpected ways.
Names indicate purpose
An identifier should indicate the function of the variable/function/etc. that it represents, e.g. foobar is probably not a good name for a variable storing the age of a person.
Identifier names should also be descriptive. n might not be a good name for a global variable representing the number of employees. However, a good medium between long names and lots of typing has to be found. Therefore, this rule can be relaxed for variables that are used in a small scope or context. Many programmers prefer short variables (such as i) as loop iterators.
Capitalization
Conventionally, variable names start with a lower case character. In identifiers which contain more than one natural language words, either underscores or capitalization is used to delimit the words, e.g. num_chars (K&R style) or numChars (Java style). It is recommended that you pick one notation and do not mix them within one project.
Constants
When naming #defines, constant variables, enum constants. and macros put in all uppercase using '_' separators; this makes it very clear that the value is not alterable and in the case of macros, makes it clear that you are using a construct that requires care.
|
NOTE: |
Functions and Member Functions
The name given to functions and member functions should be descriptive and make it clear what it does. Since usually functions and member functions perform actions, the best name choices typically contain a mix of verbs and nouns in them such as CheckForErrors() instead of ErrorCheck() and dump_data_to_file() instead of data_file(). Clear and descriptive names for functions and member functions can sometimes make guessing correctly what functions and member functions do easier, aiding in making code more self documenting. By following this and other naming conventions programs can be read more naturally.
People seem to have very different intuitions when using names containing abbreviations. It's best to settle on one strategy so the names are absolutely predictable. Take for example NetworkABCKey. Notice how the C from ABC and K from key are confused. Some people don't mind this and others just hate it so you'll find different policies in different code so you never know what to call something.
Prefixes and suffixes are sometimes useful:
- Min - to mean the minimum value something can have.
- Max - to mean the maximum value something can have.
- Cnt - the current count of something.
- Count - the current count of something.
- Num - the current number of something.
- Key - key value.
- Hash - hash value.
- Size - the current size of something.
- Len - the current length of something.
- Pos - the current position of something.
- Limit - the current limit of something.
- Is - asking if something is true.
- Not - asking if something is not true.
- Has - asking if something has a specific value, attribute or property.
- Can - asking if something can be done.
- Get - get a value.
- Set - set a value.
Examples
In most contexts, leading underscores are also better avoided. For example, these are valid identifiers:
- i loop value
- numberOfCharacters number of characters
- number_of_chars number of characters
- num_chars number of characters
- get_number_of_characters() get the number of characters
- get_number_of_chars() get the number of characters
- is_character_limit() is this the character limit?
- is_char_limit() is this the character limit?
- character_max() maximum number of a character
- charMax() maximum number of a character
- CharMin() minimum number of a character
These are also valid identifiers but can you tell what they mean:
- num1
- do_this()
- g()
- hxq
The following are valid identifiers but better avoided:
- _num as it could be used by the compiler/system headers
- num__chars as it could be used by the compiler/system headers
- main as there is potential for confusion
- cout as there is potential for confusion
The following are not valid identifiers:
- if as it is a keyword
- 4nums as it starts with a digit
- number of characters as spaces are not allowed within an identifier
Reduced use of keywords
Like for instance not using inline if the member function is implicitly inlined.
|
NOTE: |
25 lines 80 columns
This is a commonly recommended but often inapplicable rule. Many people say it's an outdated rule, that it comes from prehistoric times when terminals could only display 25 lines 80 columns.
This rules signifies that if you are writing code that will go further than 80 columns or 25 lines, it's time to think about splitting the code into functions. This recommended practice relates also to the 0 means success convention for functions, that we will cover on the Functions Section of this book.
This practice will will save you precious time when you have to return to a project you haven't been working on for 6 months.
Whitespace and Indentation
|
Conventions followed when using whitespace to improve the readability of code is called an indentation style. Every block of code and every definition should follow a consistent indention style. This usually means everything within { and }. However, the same thing goes for one-line code blocks.
Use a fixed number of spaces for indentation. Recommendations vary; 2, 3, 4, 8 are all common numbers. If you use tabs for indention you have to be aware that editors and printers may deal with, and expand, tabs differently. The K&R standard recommends an indentation size of 2 spaces.
For example, a program could as well be written using the follows:
// Using an indentation size of 2 if ( a > 5 ) { b=a; a++; }
However, the same code could be made much more readable with proper indentation:
// Using an indentation size of 2 if ( a > 5 ) { b=a; a++; } // Using an indentation size of 4 if ( a > 5 ) { b=a; a++; }
Placement of braces (curly brackets)
As we have seen early on the Statements Section, compound statement are very important in C++, they also are subject of different coding styles, that recommend different placements of opening and closing braces ({ and }). Some recommend putting the opening brace on the line with the statement, at the end (K&R). Others recommend putting these on a line by itself, but not indented (ANSI C++). GNU recommends putting braces on a line by itself, and indenting them half-way. We recommend picking one brace-placement style and sticking with it.
Examples:
if (a > 5) { // This is K&R style } if (a > 5) { // This is ANSI C++ style } if (a > 5) { // This is GNU style }
Comments
Comments are portions of the code ignored by the compiler which allow the user to make simple notes in the relevant areas of the source code. Comments come either in block form or as single lines.
|
|
NOTE: |
We will now describe how a comment can be added to the source code, but not where how and when to comment, we will get into that later.
C Comments
If you use this kind of comment try to use it like this... Commented
/*void EventLoop(); /**/
or for multiple lines
/*
void EventLoop();
void EventLoop();
/**/
this opens you the option to do this... Uncommented
void EventLoop(); /**/
or for multiple lines
void EventLoop(); void EventLoop(); /**/
|
NOTE: |
... by removing only the start of comment and so activating the next one, you did re-activate the commented code, because if you start a comment this way it will be valid until it finds the close of comment */.
|
NOTE: int function() /* This is a comment /* { return 0; } and this is the same comment */ so this isn't in the comment, and will give an error*/ because of the text so this isn't in the comment */ at the end of the line which is not inside the comment; the comment ends at the first */ pair it finds, ignoring any interim /* pairs which might look to human readers like the start of a nested comment. |
C++ Comments
C++ comments start with // and continue until the end of the line. or find the backslash \ character.
Example:
// This is a single one line comment
or
if (expression) // This needs a comment { statements; } else { statements; }
The backslash is a continuation character and will continue the comment to the following line:
// This comment will also comment the following line \
std::cout << "This line will not print" << std::endl;
- Using comments to temporarily ignore code
Comments are also sometimes used to enclose code that we temporarily want the compiler to ignore. This can be useful in finding errors in the program. If a program does not give the desired result, it might be possible to track which particular statement contains the error by commenting out code.
- With C comments
C-style comments (that start with /* and end with */) can stop before the end of the line and can be used to "comment out" a small portion of code within a line in the program since there is no restriction to what is contained between the comment delimiters.
Example:
/* This is a single line comment */
or
/*
This is a multiple line comment
*/
- C and C++ Style
Combining multi-line comments (/* */) with c++ comments (//) to comment out multiple lines of code:
Commenting out the code:
/*
void EventLoop();
void EventLoop();
void EventLoop();
void EventLoop();
void EventLoop();
//*/
uncommenting the code chunk
//* void EventLoop(); void EventLoop(); void EventLoop(); void EventLoop(); void EventLoop(); //*/
This works because a //* is still a c++ comment. And //*/ acts as a c++ comment and a multi-line comment terminator. However this doesn't work if there are any multi-line comments are used for function descriptions.
- Note on doing it with preprocessor statements
Another way (considered bad practice) is to selectively enable disable sections of code:
#if(0) // Change this to 1 to uncomments. void EventLoop(); #endif
this is considered a bad practice because the code often become illegible when several #if are mixed, if you use them don't forget to add a comment at the #endif saying what #if it correspond
#if (FEATURE_1 == 1) do_something; #endif //FEATURE_1 == 1
you can prevent illegibility by using inline functions (often considered better than macros for legibility with no performance cost) containing only 2 sections in #if #else #endif
inline do_test() { #if (Feature_1 == 1) do_something #endif //FEATURE_1 == 1 }
and call
do_test();
in the program
|
NOTE: If your comment lies into one line with code, use C++ style. |
Document your code
There are a number of good reasons to document your code, and a number of aspects of it that can be documented. Documentation provides you with a shortcut for obtaining an overview of the system or for understanding the code that provides a particular feature.
Why ?
The purpose of comments is to explain and clarify the source code to anyone examining it

