Introduction to C++
Just getting started? We can help.
Contents
What is C++?
C++ (pronounced “cee plus plus”) is a general-purpose programming language with features found both in very high-level languages and in very low-level languages.
Its name is in part a pun on the C increment-by-one operator, reflecting its nature as an evolution of the C programming language.
C++ adds
object oriented programming capabilities to C: the use of
classes,
virtual methods, and
multiple inheritance. It also adds
reference types,
operator overloading,
templates,
namespaces, and
exception handling.
Recent enhancements include minor additions to the language (such as
rvalue references and
type inference) and a good many extensions and improvements to the C++ Standard Library.
As a result, it takes some time and effort to become familiar with
all of the language’s capabilities – but there is no reason why you should not start using it proficiently right away.
Is C++ a proprietary language?
No, no one owns the C++ language. Anyone can use it royalty-free.
The
C++ Standards Committee is an international organization that maintains the definition of the language. If you want an official copy of the C++ Standard you do need to pay them for it; however, unless you are writing a C++ compiler, you really don’t need it. You can get draft versions for free.
Also, you may need to buy a compiler to write C++ programs. For most computer systems there are excellent royalty-free options available. See
below for more.
C++ is closely linked to C, so both C and C++ standards are listed here.
K&R C
This is the C designed and published by the legendary
Brian Kernighan and
Dennis Ritchie, famous for their work in the development of Unix and C. (Ritchie created C and co-created Unix with
Ken Thompson.)
It is obsolete.
Many C aficionados still have their famous K&R C handbook (
The C Programming Language), which still serves as excellent reading for those interested in a deeper understanding of C (and, consequently, C++).
C89 or ANSI C — ANSI X3.159-1989
This is what most people think of when they think of C. It is the first true ‘standard’ version of the language. Before ANSI-C, many C implementations were incompatible in important ways, making it difficult to write a program that worked on multiple computer systems.
It is today the most widely-implemented programming language of all time. There are very few computer systems for which an ANSI-C compiler does not exist.
C90 — ISO/IEC 9899:1990
This is essentially the same language as C89 — the difference is simply that it is an ISO/IEC (an international body) standard publication instead of an ANSI (an American body) publication.
C++ was designed against C90.
C99 — ISO/IEC 9899:1999
C99 is a radically modified version of the C programming language; its aims are different than, and often antagonistic to, those of the C++ language.
Many compiler systems can handle both C and C++ programs, and as a result, some things unique to C99 find their way into C++, either intentionally or not.
Since C99 specifically diverges from compatibility with C++, it is often treated as an entirely different beast than the C89/90 and C++ languages. Many members here on the forum are familiar with it, though.
C11 — ISO/IEC 9899:2011
C11 is the most recent version of C. It standardizes many things that C99 compilers commonly allow, and tightens the way memory is treated to better support threading. It does, however, make implementation of many features optional, which, if history shows us anything, may make portability problematic for some programs.
C++98 — ISO/IEC 14882:1998
C++, when first created by Bjarne Stroustrup, was a work in progress. Many older compiler systems implemented a pre-standard version of C++. It took many years for the C++ language to get to a stable state.
Once it did, it was standardized by the ISO/IEC (an international body), in 1998.
C++03 — ISO/IEC 14882:2003
This is a minor revision to C++98.
C++11 (previously C++0x) — ISO/IEC 14882:2011
This is long-anticipated update to C++, which solves some vexing issues with the language. It also adds significant capabilities to the Standard Library, such as threading, that were previously only available through
Boost or other third-party libraries.
How do I know if my compiler supports a Standard?
Most compilers today are pretty clear about what they do and do not support in the C++ standards, though sometimes you do have to dig a bit into the documentation. Older, pre-standard compilers are more likely to leave you wondering. However, even today there are some parts of the standards that your compiler may not support (yet).
Pre-Standard C++
A pre-standard C++ program will look something like the following. It is what you are likely to see if you are using something like the old
Borland C++ compiler suite; it will not compile using an ANSI C++ compiler.
1 2 3 4 5 6
|
#include <iostream.h>
int main()
{
cout << "Hello world!\n";
return 0;
}
|
ANSI C++
An ANSI C++ / C++98 compiler will support the following. Notice the use of
namespaces,
templates, and the
bool datatype. (If it does
not support it, it will fail to compile.)
1 2 3 4 5 6 7 8 9 10 11
|
#include <iostream>
using namespace std;
template <typename T>
bool ansisupported( T x ) { return true; }
int main()
{
if (ansisupported(0)) cout << "Supports ANSI C++\n";
return 0;
}
|
Until very recently, and even now, many C++ compilers lack support for important language features.
ANSI C++ Partial Template Specialization
The following code tests for Partial Template Specialization. If your compiler is too old, it will either not compile or not execute correctly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include <iostream>
using namespace std;
template <typename T, int N>
struct NoThree
{
T value() const { return N; }
};
template <typename T>
struct NoThree <T, 3>
{
T value() const { return 0; }
};
int main()
{
cout << "NoThree <int, 7> ().value() = " << NoThree <int, 7> ().value() << endl; // prints 7
cout << "NoThree <int, 3> ().value() = " << NoThree <int, 3> ().value() << endl; // prints 0
return 0;
}
|
Another simple test is if your compiler properly supports the
iterator_traits <> class, which requires partial specialization to work.
ANSI C++ Partial Template Function Ordering
Some compilers do not properly support Partial Template Function Ordering (also called
Partial Ordering of Function Templates). Generic code (or templates) can make it possible for multiple template choices to be applicable when calling with given arguments; the compiler is supposed to make the
most specific possible choice. If it doesn’t, the following will either get an ‘ambiguous function call’ compile error or it will execute incorrectly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include <iostream>
using namespace std;
template <typename T> void f( T ) { cout << "least specialized\n"; }
template <typename T> void f( T* ) { cout << "more specialized\n"; }
template <typename T> void f( const T* ) { cout << "most specialized\n"; }
int main()
{
int mi = 7;
const int ci = 42;
f( mi ); // least specialized
f( ci ); // least specialized
f( &mi ); // more specialized
f( &ci ); // most specialized
return 0;
}
|
C++11
The current C++11 standard is very well designed, and many compilers are quickly moving towards full compliance. If you have a compiler that claims C++11 support, you should be able to compile the following. Notice the use of
lambda expressions,
auto,
static_assert(), and
rvalue references.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
#include <cctype>
#include <iostream>
#include <type_traits>
using namespace std;
#define ARRAY_LENGTH( a ) extent <decltype( a )> ::value
int main()
{
const char name[] = "jenNiFeR";
// static_assert(), of course
static_assert(
ARRAY_LENGTH( name ) > 1,
"A person's name must be at least one letter long." );
// auto, lambda, rvalue references
auto titlecase = []( string&& s ) -> string&
{
bool last_not_alpha = true;
for (auto& c : s)
{
c = last_not_alpha ? toupper( c ) : tolower( c );
last_not_alpha = !isalpha( c );
}
return s;
};
// Today, everyone's Irish
cout << titlecase( string( name ) + " o'kEEfE" ) << "\n";
return 0;
}
|
Even with all that, there are still a couple of important areas in the new standard that your compiler may not support.
C++11 Constructor Inheritance
The following code tests for proper Constructor Inheritance. (Sadly, as of this writing, there are not any compilers that actually support inherited constructors. Mind you, this is not the same as
delegating constructors, which some compilers
do support.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
#include <iostream>
#include <string>
using namespace std;
struct A
{
string s;
A( const string& s = string() ):
s( s.empty() ? string( "world" ) : s ) { }
string hello() const
{ return string( "Hello " ) + s + "!"; }
};
struct B: public A
{
using A::A; // Inherit ALL of A's constructors
string goodbye() const
{ return string( "Goodbye " ) + s + "!"; }
};
int main()
{
string s;
cout << "Whom do you wish to greet? ";
getline( cin, s );
B user( s );
cout << user.hello() << endl;
cout << user.goodbye() << endl;
return 0;
}
|
C++11 Variadic Templates
The other important update to the standard is Variadic Templates. It may not seem like much, but it actually has significant consequences in source code size and simplicity, compile times, and final executable size, particularly as it relates to the STL. Here’s the test:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#include <iostream>
#include <string>
using namespace std;
template <typename Name>
void greet0( Name name )
{
cout << " and " << name;
}
template <typename Name, typename... Names>
void greet0( Name name, Names... names )
{
cout << " " << name << ",";
greet0( names... );
}
template <typename Name, typename... Names>
void greet( Name name, Names... names )
{
cout << "Hello " << name << ",";
greet0( names... );
cout << "!\n";
}
int main()
{
string girl = "Little Red-Haired Girl";
greet( "Charlie Brown", 5, "Linus", "Lucy", girl );
return 0;
}
|
Keep in mind that if your compiler fails this test the STL will still work properly for you. (It will just be bigger and take a longer time to compile because of all the internal meta-macro programming that must be done to compensate – which is what you’ve had to deal with up until now anyway.)
C++11 Lambda as Function Pointer
A simple
lambda is supposed to decompose to a
function pointer. Some compilers cannot yet do it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void print_if( vector <string> & vs, bool (*f)( const string& s ) )
{
for (auto s: vs) if (f( s ))
{
cout << " " << s << "\n";
}
}
int main()
{
vector <string> names( {
"Alanna", "Georgio", "Hannah", "Annie", "Alonzo", "Frederick", "Joanna"
} );
print_if( names, []( const string& s )
{
return s.find( "nn" ) != string::npos;
} );
return 0;
}
|
Additional Standards Support Resources
For more portability and compiler standards compliance issues, see
ISOcxx: The C++ Portability Package (from which some of the above examples are derived), and
Apache’s C++0x Compiler Support matrix page.
For a couple individual compilers’ C++ standards support:
GCC,
VC++,
Clang.
Do I need to learn C or another language first?
No, you do
not need to learn C (or any other language) first.
Keep in mind that this question starts Holy Wars among devotees of various languages, and particularly among those who still see C++ with some degree of bias.
C++ is a language in its own right, and it is just as easy to learn C++ memes as it is to learn any other language’s way of doing things. While learning other languages in addition to C++ is an excellent expenditure of your time, C++ isn’t so difficult that you need to be educated with someone else’s idea of what you ought to know first.
That is, if you want to learn C++, don’t waste your time with anything else; just learn C++.
As for C in particular, there is good reason
not to learn it first, particularly if you are a beginner. C++ has been called ‘a better C,’ but it really is a different language. The way you think about and do things is different in C++ than C. Moreover, many ways of doing things in C are the wrong way in C++.
For this reason, many people will respond along the lines that you will have to ‘unlearn’ C to learn C++, meaning that there is no point in cluttering your mind with a different, conflicting methodology than the one you intend to learn.
When you arrive at the point that it actually makes a difference, you will already have learned C and other languages sufficient to understand and apply the important principles behind their designs and uses to C++.
How can I best learn C++?
There is no one true method. Your choice will depend on the time you have to invest and your preferences.
Many trade schools and universities around the world have classes in C++ and computer programming. However, many people learn it with only the help of books, tutorials, and other online resources.
Here at
cplusplus.com we have a very nice
Documentation section that quickly covers all the important features of C++. We also have a very nice
Reference section that contains detailed information about the C++ Standard Library and its use, replete with examples. Finally, there are many
Articles that illuminate various concepts to effectively using C++. You might also want to pick up some
good books.
What do I need to get started?
At the very minimum, you need a text editor and a
compiler. A favorite option is an
Integrated Development Environment, or IDE, which combines those two and adds additional features. The advantage of an IDE is that it often facilitates creating
windowed applications.
It is also recommended that you also install the
Boost Libraries. Boost is where the people who develop and maintain the C++ Standard Library play around.
If you are planning to develop using a specific technology or on a specific system, it is worth installing libraries that are used on that system. For example, if you plan to write applications that use the GNOME Linux desktop environment, you will have to install
GTK+. If you plan to develop KDE Linux desktop applications, you will need to install
Trolltech Qt and the
KDE Development Platform. If you plan to develop on Microsoft Windows, you will definitely want the
Windows API, which you should be able to get with your Windows compiler.
A good place to look around for compilers and libraries is
Freebyte’s Guide To... Free C++ (and C) Programming Tools.
You should also have access to a good
search engine, so you can surf the web to understand the error messages you will get when compiling.
Finally, you will want to find and read as much reference material and tutorials as you can. This site maintains an excellent introductory
Tutorial, and there exist
many good C++ books.
What is Boost? And why do I want it?
You are not mistaken. We think you should spend some time
installing the
Boost Libraries in addition to your standard C++ setup.
The Boost Libraries are maintained by the very same people who designed and built the standard C++ libraries. They are designed to extend C++ in an efficient, commercial-grade, universally applicable way. The vast majority of the updates to the STL in C++11, and in the TR1 (
Technical Report) and upcoming TR2 library extensions came straight from Boost.
The
Boost License specifically makes the libraries very friendly to both commercial and non-commercial purposes. Many, many people around the world contribute to and peer-review the code.
The goal of Boost’s maintainers is ‘to establish “existing practice” and provide reference implementations so that Boost libraries are suitable for eventual standardization.’
It is worth your time.
Why not get started? The instructions are relatively straight-forward, but if you do have trouble, make sure to ask for help on the
forums.
What is Object Oriented Programming?
Unlike the hype (and perhaps what you have been taught), OOP is very easy to grasp; but first a little history.
imperative
In the early days, a program was composed of a sequence of
commands that operated on named
variables and/or directly on a piece of memory. Flow control was limited to simple loop and
branch structures (like
if and
goto); otherwise the program ran from the beginning of the code to the end. There was no concept of private data, and code had to be carefully written not to modify the wrong thing at the wrong time. Examples of this are Assembly language, early BASIC dialects, and DOS BATCH files.
structured
In the 1960s a new type of programming language began to be designed that introduced a more orderly flow control on the program code, such as: grouping related
statements (expressions which may incorporate commands or calculations) into
blocks that could be treated as if they were a single statement,
subroutines, and a whole litany of loop and branch constructs (like
do..
while and
switch, respectively). Likewise, related data could be structured into
compound types (
records, or what we call
structs in C and C++, and
arrays).
procedural
Shortly after that a real paradigm shift occurred, where
modular programming techniques were introduced. The idea is to make more complex programs out of smaller, separate components, or modules, that accomplish a single parameterized task. Here we have the introduction of
scope: local, private data and visibility; sequencing and true iteration (unlike the batch programs of before); and modular procedural types that
return a value directly without the need for direct environmental accesses – procedures interact with their environment according to how they are instructed via arguments. (In C and C++, we call these things
functions.) This also made possible
libraries of reusable code.
object-oriented
Unlike the hype, OOP is not really another revolution, just a different way of looking at the same thing. In procedural programming,
procedures need to know how to handle the objects (or data) that they are manipulating. Data gets passed around and modified by procedures. It can become something of a hassle to choose between procedures to apply to a given piece of data.
In OOP, a piece of data has procedures attached to it, so that, in a sense, data knows how to operate on itself. Said another way, the data has an association with the correct procedures to use on it, so that by simply having the data you can operate on it without having to directly decide exactly which procedure is appropriate to use. In this case, the procedures are called
methods.
There are typically four distinct concepts that define Object-Oriented Programming (some debate exists about what exactly those concepts are, but we’ll stick with these four):
- Data Abstraction — This is the concept that things should be designed and used in terms of how they appear to the outside world and not their internal workings.
- Encapsulation (or Data Hiding) — This means that both access to and the view of underlying data is controlled. (Notice how this logically derives from the idea of data abstraction.)
- Inheritance — This is a way of designing new kinds of things by extending an existing kind of thing. For example, a Red Delicious and a Granny Smith are specializations of an abstract ‘apple’. This is the ‘is a’ kind of relationship between data. (A Granny Smith ‘is an’ apple.)
- Polymorphism — This is the ability to automatically choose the correct behavior of a thing when you know nothing more about it than its ‘is a’ relationship. Continuing with the fruit, if your program has an apple, it can ask what color the apple is, knowing nothing more about the apple than ‘it is an apple’. A Granny Smith apple will report that it is green, while a Red Delicious will report that it is red.
Another way of thinking about it is that is that an object combines
state and
behavior. A simple example would be a sprite in a video game, such as Mario. Mario always has a specific
state: position, speed, mushroom last eaten, etc; and a specific
behavior: how he reacts to his environment given his current state.
If you are familiar with
functional programming, then you could say that an object is the non-functional version of a
closure.
There is more to it than that, but those are the basics, sufficient to get you started.
What are templates and ‘generic programming’?
Generic programming is a technique that allows you to write code that works over a broad range of datatypes instead of one single datatype. For example, let’s say we have a list of numbers we wish to sum.
int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 21 };
Let’s write a function to sum them:
1 2 3 4 5 6
|
int sum( int* ns, size_t len )
{
int result = 0;
while (len) result += ns[ --len ];
return result;
}
|
Clearly, that code works fine for summing arrays of
integers. But what if we want to sum a sequence of floating-point numbers?
double harmonic7[] = { 1.0/1, 1.0/2, 1.0/3, 1.0/4, 1.0/5, 1.0/6, 1.0/7 };
We would have to rewrite the
sum() function.
1 2 3 4 5 6
|
double sum( double* ns, size_t len )
{
double result = 0.0;
while (len) result += ns[ --len ];
return result;
}
|
Now suppose some engineer then comes by and says, “Wait, I need to sum a bunch of
std::complex numbers.” You would have to write yet
another version of the function.
In C++, you can instead write a
template, or a blueprint, of a function that the compiler can use to actually create a function as needed. We’ll rewrite our
sum() as a blueprint version, and toss all the other versions:
1 2 3 4 5 6 7
|
template <typename T>
T sum( T* ns, size_t len )
{
T result = T();
while (len) result += ns[ --len ];
return result;
}
|
What that says is that the compiler can replace every ‘T’ with the actual datatype needed to create a new function. So now we can use it as if we had manually overloaded for whatever type we want:
9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include <iostream>
using namespace std;
int main()
{
int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 21 };
cout << "sum of 9 primes = " << sum( primes, 9 ) << endl;
double harmonic7[] = { 1.0/1, 1.0/2, 1.0/3, 1.0/4, 1.0/5, 1.0/6, 1.0/7 };
cout << "sum of first 7 harmonics = " << sum( harmonic7, 7 ) << endl;
return 0;
}
|
That’s not all. You can also write templated object types (or classes). See the
Tutorial for a more in-depth discussion of templates and generic programming.
How do I make windowed (GUI) programs?
That depends on what you mean.
Game Applications 
A game application is the kind that normally works fullscreen, taking over your entire interaction with the computer. It has fancy graphics, using either a 2D graphics engine like
SDL or
SFML or a 3D graphics engine like
DirectX,
OpenGL, or
Ogre3D. Many others exist.
There is a very good list over at Wikipedia.org.
Desktop Applications 
A desktop application is the kind you normally use on your computer, like your word processor, internet browser, calculator, email client, text editor or IDE, etc. It is usually distinguished because it has window borders and works with your Window Manager (like the Microsoft Desktop, or GNOME or KDE, etc), and you can use multiple applications at the same time. The elements you interact with are text, buttons, drop-down boxes, dialogs, etc.
You need a GUI Toolkit. And you need to learn how to use it. And that takes a lot of learning, alas. (And for some of them, it also takes a lot of money.)
If you are looking for free software, your choices are not necessarily as friendly as the commercial development tools, but they are very usable.
Also nice is a
forms designer, which allows you to drag-and-drop the design of your application. Some toolkits come with a forms designer integrated into the IDE; some do not.
In no particular order, here are the most popular C and C++ toolkits:
| Product |
IDE |
Forms Designer |
Platform Support |
License |
| Visual C++ |
yes |
integrated |
Windows |
Free and Commercial editions available |
| Embarcadero RAD Studio XE2 |
yes |
integrated |
Multi-platform |
Commercial only |
| Trolltech Qt Framework |
Qt Creator IDE |
Multi-platform |
Qt LGPL and Qt Commercial editions available |
| FOX Toolkit |
no |
|
Multi-platform |
LGPL |
| wxWidgets |
no |
3d party tools |
Multi-platform |
wxWidgets License (modified LGPL) |
| FLTK |
no |
FLUID |
Multi-platform |
LGPL |
| GTK |
no |
Glade |
Linux/Windows/Mac |
LGPL |
| XForms |
no |
fdesign |
Unix/Linux/anything that runs X |
LGPL |
| Xcode |
yes |
integrated Interface Builder |
Mac OS X |
Apple Developer License |
There are, of course, many, many others. You can always peruse sites like
The GUI Toolkit, Framework Page and
Wikipedia. Some cross-platform IDEs, like Code::Blocks and Eclipse, can integrate with third-party forms designers.
The other option is to develop directly against your OS’s Window library.
The Windows API and Cocoa frameworks make it very simple and straight-forward to develop directly. X, however, was designed with a completely different underlying architecture and philosophy – which isn’t wrong – that has proven a little unwieldly at times.
What are Visual C++ and ‘visual programming’?
Visual C++ is Microsoft’s C++ development environment, and in this context, ‘visual programming’ refers to using the IDE (or
Integrated Development Environment) to drag and drop and design the GUI aspects of the program along with integrated access to the code. The idea was pioneered by both
Microsoft and
Borland and it is today a very common IDE design.
Microsoft Visual C++ Express is the free version. Microsoft, of course, also offers the Professional, Premium, and Ultimate editions, which cost money (but with good reasons to want to spend it).
(Outside of this context, the term
visual programming actually refers to more of a flowchart or widget-interface application that allows you to design a program or sequence of some sort without having to write in a more traditional, text-based programming language or markup language.
Read more on Wikipedia.)