Introduction to C++


Just getting started? We can help.

Contents

What is C++?
Is C++ a proprietary language? Do I need to pay to use it?
What are the C++ Language Standards?
How do I know if my compiler supports a Standard?

Do I need to learn C or another language first?
How can I best learn C++?
What do I need to get started?
What is Boost? And why do I want it?

What is OOP (Object Oriented Programming)?
What are templates and ‘generic programming’?
How do I make windowed (GUI) programs?
What is Visual C++? What does ‘visual programming’ mean?

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.

What are the C++ Language Standards?

C++ is closely linked to C, so both C and C++ standards are listed here.

 C standards  C++ standards 
K&R C
C89 / ANSI C
C90
C99
C11
C++98
C++03
C++11 / C++0x



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).

 C++ standards 
Pre-standard C++
ANSI C++
ANSI C++ Partial Template Specialization
ANSI C++ Partial Template Function Ordering
C++11
C++11 Constructor Inheritance
C++11 Variadic Templates
C++11 Lambda to Function Pointer
Additional Standards Support Resources

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):
  1. 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.
  2. 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.)
  3. 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.)
  4. 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.

OS-Specific Windowing APIs
OS API Tutorials
Microsoft Windows Windows API theForger’s Win32 API Tutorial
Relisoft Windows API Tutorial
Unix and Linux XLib Xlib programming: a short tutorial
Basic Graphics Programming With The Xlib Library
XLib has some interesting design characteristics, and can be fun, but you are insane if you want to develop on it directly. Use something else. Otherwise, (say you are developing the next GUI toolkit) buy some books:
Xlib Programming Manual
Xlib Reference Manual R5
Unix and Linux Xt (X Intrinsics) X tutorial
The X Toolkit Intrinsics F.A.Q
This was supposed to make XLib easier, but few people have adapted it.
Seriously, get a couple of books:
X Toolkit Intrinsics Programming Manual
X Toolkit Intrinsics Reference Manual
Mac OS X Cocoa Use Xcode

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.)