C++ - Wikipedia
C++ - Wikipedia
History
Logo endorsed by
the C++ standards
committee
Bjarne Stroustrup, the creator of C++,
in his AT&T New Jersey office, c. 2000 Paradigms Multi-
In 1979, Bjarne Stroustrup, a Danish computer
scientist, began work on "C with Classes", the
paradigm
predecessor to C++.[21] The motivation for
creating a new language originated from
procedura
Stroustrup's experience in programming for
his PhD thesis. Stroustrup found that Simula
imperativ
had features that were very helpful for large
software development, but the language was
functiona
too slow for practical use, while BCPL was
fast but too low-level to be suitable for large
object-
software development. When Stroustrup
started working in AT&T Bell Labs, he had the
oriented,
problem of analyzing the UNIX kernel with
respect to distributed computing.
generic,
Remembering his PhD experience, Stroustrup
set out to enhance the C language with
modular
Simula-like features.[22] C was chosen
because it was general-purpose, fast, Family C
portable, and widely used. In addition to C and
Simula's influences, other languages Designed by Bjarne
influenced this new language, including
ALGOL 68, Ada, CLU, and ML. Stroustr
Initially, Stroustrup's "C with Classes" added
features to the C compiler, Cpre, including Developer ISO/IEC JT
classes, derived classes, strong typing,
inlining, and default arguments.[23] (Joint
Technical
Committe
SC 22
Etymology Major
implementations
According to Stroustrup, "the name signifies
the evolutionary nature of the changes from
C."[32] This name is credited to Rick Mascitti GCC, LLVM Clang,
(mid-1983)[23] and was first used in December
1983. When Mascitti was questioned Microsoft Visual C++,
informally in 1992 about the naming, he
indicated that it was given in a tongue-in- Embarcadero C++Buil
cheek spirit. The name comes from C's ++
operator (which increments the value of a , Intel C++ Compiler,
variable) and a common naming convention
of using "+" to indicate an enhanced computer IBM XL C++, EDG
program.
implementable at Wikibooks
(with a reasonably obvious way to do
so).
Programmers should be free to pick
their own programming style, and that
style should be fully supported by C++.
Allowing a useful feature is more
important than preventing every
possible misuse of C++.
It should provide facilities for organising
programs into separate, well-defined
parts, and provide facilities for
combining separately developed parts.
No implicit violations of the type system
(but allow explicit violations; that is,
those explicitly requested by the
programmer).
User-created types need to have the
same support and performance as built-
in types.
Unused features should not negatively
impact created executables (e.g. in
lower performance).
There should be no language beneath
C++ (except assembly language).
C++ should work alongside other
existing programming languages, rather
than fostering its own separate and
incompatible programming
environment.
If the programmer's intent is unknown,
allow the programmer to specify it by
providing manual control.
Standardization
C++ is standardized by an ISO working group known C++ standards
as JTC1/SC22/WG21. So far, it has published six
Year ISO/IEC Standard Informal name
revisions of the C++ standard and is currently
1998 14882:1998[34] C++98
working on the next revision, C++23.
2003 14882:2003[35] C++03
In 1998, the ISO working group standardized C++ for the first time as ISO/IEC 14882:1998, which
is informally known as C++98. In 2003, it published a new version of the C++ standard called
ISO/IEC 14882:2003, which fixed problems identified in C++98.
The next major revision of the standard was informally referred to as "C++0x", but it was not
released until 2011.[39] C++11 (14882:2011) included many additions to both the core language
and the standard library.[36]
In 2014, C++14 (also known as C++1y) was released as a small extension to C++11, featuring
mainly bug fixes and small improvements.[40] The Draft International Standard ballot procedures
completed in mid-August 2014.[41]
After C++14, a major revision C++17, informally known as C++1z, was completed by the ISO C++
committee in mid July 2017 and was approved and published in December 2017.[42]
As part of the standardization process, ISO also publishes technical reports and specifications:
Language
The C++ language has two main components: a direct mapping of hardware features provided
primarily by the C subset, and zero-overhead abstractions based on those mappings. Stroustrup
describes C++ as "a light-weight abstraction programming language [designed] for building and
using efficient and elegant abstractions";[15] and "offering both hardware access and abstraction
is the basis of C++. Doing it efficiently is what distinguishes it from other languages."[60]
C++ inherits most of C's syntax. The following is Bjarne Stroustrup's version of the Hello world
program that uses the C++ Standard Library stream facility to write a message to standard
output:[61][62][note 2]
1 #include <iostream>
2
3 int main()
4 {
5 std::cout <<
"Hello, world!\n";
6 }
Object storage
As in C, C++ supports four types of memory management: static storage duration objects,
thread storage duration objects, automatic storage duration objects, and dynamic storage
duration objects.[63]
Static storage duration objects are initialized in two phases. First, "static initialization" is
performed, and only after all static initialization is performed, "dynamic initialization" is
performed. In static initialization, all objects are first initialized with zeros; after that, all objects
that have a constant initialization phase are initialized with the constant expression (i.e.
variables initialized with a literal or constexpr ). Though it is not specified in the standard,
the static initialization phase can be completed at compile time and saved in the data partition
of the executable. Dynamic initialization involves all object initialization done via a constructor or
function call (unless the function is marked with constexpr , in C++11). The dynamic
initialization order is defined as the order of declaration within the compilation unit (i.e. the same
file). No guarantees are provided about the order of initialization between compilation units.
Local variables are created as the point of execution passes the declaration point. If the variable
has a constructor or initializer this is used to define the initial state of the object. Local variables
are destroyed when the local block or function that they are declared in is closed. C++
destructors for local variables are called at the end of the object lifetime, allowing a discipline
for automatic resource management termed RAII, which is widely used in C++.
Member variables are created when the parent object is created. Array members are initialized
from 0 to the last member of the array in order. Member variables are destroyed when the parent
object is destroyed in the reverse order of creation. i.e. If the parent is an "automatic object" then
it will be destroyed when it goes out of scope which triggers the destruction of all its members.
Temporary variables are created as the result of expression evaluation and are destroyed when
the statement containing the expression has been fully evaluated (usually at the ; at the end
of a statement).
Templates are different from macros: while both of these compile-time language features
enable conditional compilation, templates are not restricted to lexical substitution. Templates
are aware of the semantics and type system of their companion language, as well as all compile-
time type definitions, and can perform high-level operations including programmatic flow control
based on evaluation of strictly type-checked parameters. Macros are capable of conditional
control over compilation based on predetermined criteria, but cannot instantiate new types,
recurse, or perform type evaluation and in effect are limited to pre-compilation text-substitution
and text-inclusion/exclusion. In other words, macros can control compilation flow based on pre-
defined symbols but cannot, unlike templates, independently instantiate new symbols.
Templates are a tool for static polymorphism (see below) and generic programming.
Objects
C++ introduces object-oriented programming (OOP) features to C. It offers classes, which
provide the four features commonly present in OOP (and some non-OOP) languages:
abstraction, encapsulation, inheritance, and polymorphism. One distinguishing feature of C++
classes compared to classes in other programming languages is support for deterministic
destructors, which in turn provide support for the Resource Acquisition is Initialization (RAII)
concept.
Encapsulation
Encapsulation is the hiding of information to ensure that data structures and operators are used
as intended and to make the usage model more obvious to the developer. C++ provides the
ability to define classes and functions as its primary encapsulation mechanisms. Within a class,
members can be declared as either public, protected, or private to explicitly enforce
encapsulation. A public member of the class is accessible to any function. A private member is
accessible only to functions that are members of that class and to functions and classes
explicitly granted access permission by the class ("friends"). A protected member is accessible
to members of classes that inherit from the class in addition to the class itself and any friends.
The object-oriented principle ensures the encapsulation of all and only the functions that access
the internal representation of a type. C++ supports this principle via member functions and
friend functions, but it does not enforce it. Programmers can declare parts or all of the
representation of a type to be public, and they are allowed to make public entities not part of the
representation of a type. Therefore, C++ supports not just object-oriented programming, but
other decomposition paradigms such as modular programming.
It is generally considered good practice to make all data private or protected, and to make public
only those functions that are part of a minimal interface for users of the class. This can hide the
details of data implementation, allowing the designer to later fundamentally change the
implementation without changing the interface in any way.[70][71]
Inheritance
Inheritance allows one data type to acquire properties of other data types. Inheritance from a
base class may be declared as public, protected, or private. This access specifier determines
whether unrelated and derived classes can access the inherited public and protected members
of the base class. Only public inheritance corresponds to what is usually meant by "inheritance".
The other two forms are much less frequently used. If the access specifier is omitted, a "class"
inherits privately, while a "struct" inherits publicly. Base classes may be declared as virtual; this is
called virtual inheritance. Virtual inheritance ensures that only one instance of a base class
exists in the inheritance graph, avoiding some of the ambiguity problems of multiple inheritance.
Multiple inheritance is a C++ feature allowing a class to be derived from more than one base
class; this allows for more elaborate inheritance relationships. For example, a "Flying Cat" class
can inherit from both "Cat" and "Flying Mammal". Some other languages, such as C# or Java,
accomplish something similar (although more limited) by allowing inheritance of multiple
interfaces while restricting the number of base classes to one (interfaces, unlike classes,
provide only declarations of member functions, no implementation or member data). An
interface as in C# and Java can be defined in C++ as a class containing only pure virtual
functions, often known as an abstract base class or "ABC". The member functions of such an
abstract base class are normally explicitly defined in the derived class, not inherited implicitly.
C++ virtual inheritance exhibits an ambiguity resolution feature called dominance.
Polymorphism
Polymorphism enables one common interface for many implementations, and for objects to act
differently under different circumstances.
C++ supports several kinds of static (resolved at compile-time) and dynamic (resolved at run-
time) polymorphisms, supported by the language features described above. Compile-time
polymorphism does not allow for certain run-time decisions, while runtime polymorphism
typically incurs a performance penalty.
Static polymorphism
Function overloading allows programs to declare multiple functions having the same name but
with different arguments (i.e. ad hoc polymorphism). The functions are distinguished by the
number or types of their formal parameters. Thus, the same function name can refer to different
functions depending on the context in which it is used. The type returned by the function is not
used to distinguish overloaded functions and differing return types would result in a compile-
time error message.
When declaring a function, a programmer can specify for one or more parameters a default
value. Doing so allows the parameters with defaults to optionally be omitted when the function
is called, in which case the default arguments will be used. When a function is called with fewer
arguments than there are declared parameters, explicit arguments are matched to parameters in
left-to-right order, with any unmatched parameters at the end of the parameter list being
assigned their default arguments. In many cases, specifying default arguments in a single
function declaration is preferable to providing overloaded function definitions with different
numbers of parameters.
Templates in C++ provide a sophisticated mechanism for writing generic, polymorphic code (i.e.
parametric polymorphism). In particular, through the curiously recurring template pattern, it is
possible to implement a form of static polymorphism that closely mimics the syntax for
overriding virtual functions. Because C++ templates are type-aware and Turing-complete, they
can also be used to let the compiler resolve recursive conditionals and generate substantial
programs through template metaprogramming. Contrary to some opinion, template code will not
generate a bulk code after compilation with the proper compiler settings.[69]
Dynamic polymorphism
Inheritance
Variable pointers and references to a base class type in C++ can also refer to objects of any
derived classes of that type. This allows arrays and other kinds of containers to hold pointers to
objects of differing types (references cannot be directly held in containers). This enables
dynamic (run-time) polymorphism, where the referred objects can behave differently, depending
on their (actual, derived) types.
C++ also provides the dynamic_cast operator, which allows code to safely attempt
conversion of an object, via a base reference/pointer, to a more derived type: downcasting. The
attempt is necessary as often one does not know which derived type is referenced. (Upcasting,
conversion to a more general type, can always be checked/performed at compile-time via
static_cast , as ancestral classes are specified in the derived class's interface, visible to all
callers.) dynamic_cast relies on run-time type information (RTTI), metadata in the program
that enables differentiating types and their relationships. If a dynamic_cast to a pointer
fails, the result is the nullptr constant, whereas if the destination is a reference (which
cannot be null), the cast throws an exception. Objects known to be of a certain derived type can
be cast to that with static_cast , bypassing RTTI and the safe runtime type-checking of
dynamic_cast , so this should be used only if the programmer is very confident the cast is,
and will always be, valid.
In addition to standard member functions, operator overloads and destructors can be virtual. An
inexact rule based on practical experience states that if any function in the class is virtual, the
destructor should be as well. As the type of an object at its creation is known at compile time,
constructors, and by extension copy constructors, cannot be virtual. Nonetheless, a situation
may arise where a copy of an object needs to be created when a pointer to a derived object is
passed as a pointer to a base object. In such a case, a common solution is to create a
clone() (or similar) virtual function that creates and returns a copy of the derived class
when called.
A member function can also be made "pure virtual" by appending it with = 0 after the closing
parenthesis and before the semicolon. A class containing a pure virtual function is called an
abstract class. Objects cannot be created from an abstract class; they can only be derived from.
Any derived class inherits the virtual function as pure and must provide a non-pure definition of it
(and all other pure virtual functions) before objects of the derived class can be created. A
program that attempts to create an object of a class with a pure virtual member function or
inherited pure virtual member function is ill-formed.
Lambda expressions
C++ provides support for anonymous functions, also known as lambda expressions, with the
following form:
[capture](parameters) ->
return_type { function_body
}
Since C++20, the keyword template is optional for template parameters of lambda
expressions:
[capture]
<template_parameters>
(parameters) -> return_type
{ function_body }
If the lambda takes no parameters, and no return type or other specifiers are used, the () can be
omitted; that is,
[capture] { function_body }
The return type of a lambda expression can be automatically inferred, if possible; e.g.:
[](int x, int y) { return x
+ y; } // inferred
[](int x, int y) -> int {
return x + y; } // explicit
The [capture] list supports the definition of closures. Such lambda expressions are defined
in the standard as syntactic sugar for an unnamed function object.
Exception handling
Exception handling is used to communicate the existence of a runtime problem or error from
where it was detected to where the issue can be handled.[73] It permits this to be done in a
uniform manner and separately from the main code, while detecting all errors.[74] Should an error
occur, an exception is thrown (raised), which is then caught by the nearest suitable exception
handler. The exception causes the current scope to be exited, and also each outer scope
(propagation) until a suitable handler is found, calling in turn the destructors of any objects in
these exited scopes.[75] At the same time, an exception is presented as an object carrying the
data about the detected problem.[76]
Some C++ style guides, such as Google's,[77] LLVM's,[78] and Qt's,[79] forbid the usage of
exceptions.
The exception-causing code is placed inside a try block. The exceptions are handled in
separate catch blocks (the handlers); each try block can have multiple exception
handlers, as it is visible in the example below.[80]
1 #include <iostream>
2 #include <vector>
3 #include <stdexcept>
4
5 int main() {
6 try {
7
std::vector<int> vec{3,
4, 3, 1};
8 int
i{vec.at(4)}; // Throws
an exception,
std::out_of_range
(indexing for vec is
from 0-3 not 1-4)
9 }
10 // An exception
handler, catches
std::out_of_range,
which is thrown by
vec.at(4)
11 catch (const
std::out_of_range &e) {
12 std::cerr <<
"Accessing a non-
existent element: " <<
e.what() << '\n';
13 }
14 // To catch any
other standard library
exceptions (they derive
from std::exception)
15 catch (const
std::exception &e) {
16 std::cerr <<
"Exception thrown: " <<
e.what() << '\n';
17 }
18 // Catch any
unrecognised exceptions
(i.e. those which don't
derive from
std::exception)
19 catch (...) {
20 std::cerr <<
"Some fatal error\n";
21 }
22 }
It is also possible to raise exceptions purposefully, using the throw keyword; these
exceptions are handled in the usual way. In some cases, exceptions cannot be used due to
technical reasons. One such example is a critical component of an embedded system, where
every operation must be guaranteed to complete within a specified amount of time. This cannot
be determined with exceptions as no tools exist to determine the maximum time required for an
exception to be handled.[81]
Unlike signal handling, in which the handling function is called from the point of failure,
exception handling exits the current scope before the catch block is entered, which may be
located in the current function or any of the previous function calls currently on the stack.
Enumerated types
C++ has enumeration types that are directly inherited from C's and work mostly like these,
except that an enumeration is a real type in C++, giving added compile-time checking. Also (as
with structs), the C++ enum keyword is combined with a typedef, so that instead of naming
the type enum name , simply name it name . This can be simulated in C using a typedef:
typedef enum {Value1, Value2} name;
C++11 also provides a second kind of enumeration, called a scoped enumeration. These are
type-safe: the enumerators are not implicitly converted to an integer type. Among other things,
this allows I/O streaming to be defined for the enumeration type. Another feature of scoped
enumerations is that the enumerators do not leak, so usage requires prefixing with the name of
the enumeration (e.g., Color::Red for the first enumerator in the example below), unless a
using enum declaration (introduced in C++20) has been used to bring the enumerators into
the current scope. A scoped enumeration is specified by the phrase enum class (or enum
struct ). For example:
Standard library
The C++ standard consists of two parts: the core language and the standard library. C++
programmers expect the latter on every major implementation of C++; it includes aggregate
types (vectors, lists, maps, sets, queues, stacks, arrays, tuples), algorithms (find, for_each,
binary_search, random_shuffle, etc.), input/output facilities (iostream, for reading from and
writing to the console and files), filesystem library, localisation support, smart pointers for
automatic memory management, regular expression support, multi-threading library, atomics
support (allowing a variable to be read or written to by at most one thread at a time without any
external synchronisation), time utilities (measurement, getting current time, etc.), a system for
converting error reporting that does not use C++ exceptions into C++ exceptions, a random
number generator, and a slightly modified version of the C standard library (to make it comply
with the C++ type system).
A large part of the C++ library is based on the Standard Template Library (STL). Useful tools
provided by the STL include containers as the collections of objects (such as vectors and lists),
iterators that provide array-like access to containers, and algorithms that perform operations
such as searching and sorting.
Furthermore, (multi)maps (associative arrays) and (multi)sets are provided, all of which export
compatible interfaces. Therefore, using templates it is possible to write generic algorithms that
work with any container or on any sequence defined by iterators. As in C, the features of the
library are accessed by using the #include directive to include a standard header. The C++
Standard Library provides 105 standard headers, of which 27 are deprecated.
The standard incorporates the STL that was originally designed by Alexander Stepanov, who
experimented with generic algorithms and containers for many years. When he started with C++,
he finally found a language where it was possible to create generic algorithms (e.g., STL sort)
that perform even better than, for example, the C standard library qsort, thanks to C++ features
like using inlining and compile-time binding instead of function pointers. The standard does not
refer to it as "STL", as it is merely a part of the standard library, but the term is still widely used to
distinguish it from the rest of the standard library (input/output streams, internationalization,
diagnostics, the C library subset, etc.).[82]
Most C++ compilers, and all major ones, provide a standards-conforming implementation of the
C++ standard library.
The main aim is to efficiently and consistently write type and resource safe C++.
The Core Guidelines were announced[84] in the opening keynote at CPPCon 2015.
The Guidelines are accompanied by the Guideline Support Library (GSL),[85] a header only library
of types and functions to implement the Core Guidelines and static checker tools for enforcing
Guideline rules.[86]
Compatibility
To give compiler vendors greater freedom, the C++ standards committee decided not to dictate
the implementation of name mangling, exception handling, and other implementation-specific
features. The downside of this decision is that object code produced by different compilers is
expected to be incompatible. There are, however, attempts to standardize compilers for
particular machines or operating systems. For example, the Itanium C++ ABI is processor-
independent (despite its name) and is implemented by GCC and Clang.[87]
With C
C++ is often considered to be a superset of C but this is not strictly true.[88] Most C code can
easily be made to compile correctly in C++ but there are a few differences that cause some valid
C code to be invalid or behave differently in C++. For example, C allows implicit conversion from
void* to other pointer types but C++ does not (for type safety reasons). Also, C++ defines
many new keywords, such as new and class , which may be used as identifiers (for
example, variable names) in a C program.
Some incompatibilities have been removed by the 1999 revision of the C standard (C99), which
now supports C++ features such as line comments ( // ) and declarations mixed with code. On
the other hand, C99 introduced a number of new features that C++ did not support that were
incompatible or redundant in C++, such as variable-length arrays, native complex-number types
(however, the std::complex class in the C++ standard library provides similar functionality,
although not code-compatible), designated initializers, compound literals, and the restrict
keyword.[89] Some of the C99-introduced features were included in the subsequent version of the
C++ standard, C++11 (out of those which were not redundant).[90][91][92] However, the C++11
standard introduces new incompatibilities, such as disallowing assignment of a string literal to a
character pointer, which remains valid C.
To intermix C and C++ code, any function declaration or definition that is to be called from/used
both in C and C++ must be declared with C linkage by placing it within an
extern "C" {/*...*/} block. Such a function may not rely on features depending on
name mangling (i.e., function overloading).
Criticism
Despite its widespread adoption, some notable programmers have criticized the C++ language,
including Linus Torvalds,[93] Richard Stallman,[94] Joshua Bloch, Ken Thompson,[95][96][97] and
Donald Knuth.[98][99]
One of the most often criticised points of C++ is its perceived complexity as a language, with the
criticism that a large number of non-orthogonal features in practice necessitates restricting
code to a subset of C++, thus eschewing the readability benefits of common style and idioms.
As expressed by Joshua Bloch:
I think C++ was pushed well beyond its complexity threshold, and yet
there are a lot of people programming it. But what you do is you force
people to subset it. So almost every shop that I know of that uses C++
says, "Yes, we're using C++ but we're not doing multiple-
implementation inheritance and we're not using operator
overloading." There are just a bunch of features that you're not going
to use because the complexity of the resulting code is too high. And I
don't think it's good when you have to start doing that. You lose this
programmer portability where everyone can read everyone else's
code, which I think is such a good thing.
Donald Knuth (1993, commenting on pre-standardized C++), who said of Edsger Dijkstra that "to
think of programming in C++" "would make him physically ill":[98][99]
The problem that I have with them today is that... C++ is too
complicated. At the moment, it's impossible for me to write portable
code that I believe would work on lots of different systems, unless I
avoid all exotic features. Whenever the C++ language designers had
two competing ideas as to how they should solve some problem, they
said "OK, we'll do them both". So the language is too baroque for my
taste.
Ken Thompson, who was a colleague of Stroustrup at Bell Labs, gives his assessment:[96][97]
It certainly has its good points. But by and large I think it's a bad
language. It does a lot of things half well and it's just a garbage heap
of ideas that are mutually exclusive. Everybody I know, whether it's
personal or corporate, selects a subset and these subsets are different.
So it's not a good language to transport an algorithm—to say, "I wrote
it; here, take it." It's way too big, way too complex. And it's obviously
built by a committee. Stroustrup campaigned for years and years and
years, way beyond any sort of technical contributions he made to the
language, to get it adopted and used. And he sort of ran all the
standards committees with a whip and a chair. And he said "no" to no
one. He put every feature in that language that ever existed. It wasn't
cleanly designed—it was just the union of everything that came along.
And I think it suffered drastically from that.
However Brian Kernighan, also a colleague at Bell Labs, disputes this assessment:[100]
C++ has been enormously influential. ... Lots of people say C++ is too
big and too complicated etc. etc. but in fact it is a very powerful
language and pretty much everything that is in there is there for a
really sound reason: it is not somebody doing random invention, it is
actually people trying to solve real world problems. Now a lot of the
programs that we take for granted today, that we just use, are C++
programs.
Stroustrup himself comments that C++ semantics are much cleaner than its syntax: "within C++,
there is a much smaller and cleaner language struggling to get out."[101]
Other complaints may include a lack of reflection or garbage collection, long compilation times,
perceived feature creep,[102] and verbose error messages, particularly from template
metaprogramming.[103]
See also
Comparison of Computer
programming languages programming
portal
List of C++ compilers
Outline of C++
Category:C++ libraries
Footnotes
Further reading
External links
JTC1/SC22/WG21 (http://www.open-st
d.org/jtc1/sc22/wg21/) – the ISO/IEC
C++ Standard Working Group
Standard C++ Foundation (https://isocp
p.org/) – a non-profit organization that
promotes the use and understanding of
standard C++. Bjarne Stroustrup is a
director of the organization.
Retrieved from
"https://en.wikipedia.org/w/index.php?
title=C%2B%2B&oldid=1223530547"
This page was last edited on 12 May 2024, at
19:24 (UTC). •
Content is available under CC BY-SA 4.0 unless
otherwise noted.