Introduction to C++

You may copy this file for noncommercial use. Please report errors to Matt Mahoney at mmahoney@cs.fit.edu. The latest version is located at cs.fit.edu/~mmahoney/cse1502/introcpp.html updated Aug. 30, 2007. This guide is a condensed version of the longer reference at cs.fit.edu/~mmahoney/cse2050/how2cpp.html. Advanced features have been omitted.

C++ is a compiled language, producing Windows or UNIX/Linux executable programs that are typically very fast. Programs are portable between operating systems only to the extent of text I/O (input/output) and file I/O. There are Windows and UNIX/Linux libraries supporting network I/O, the mouse, and graphics, but these differ between operating systems and are beyond the scope of this document.

C++ Compilers

The g++ compiler is free for most operating systems. For Windows, it is easiest to download the MinGW g++ installer. (MinGW_Toolbox_Setup.exe, 23 MB). After installing, add C:\mingw\bin to your PATH.

Digital Mars C++ Compiler 8.49 is free. Unzip stlport.zip (2 MB) and dm849c.zip (3 MB) in C:\ to install in C:\dm and add C:\dm\bin to your PATH.

Borland C++ 5.5 is free for Windows after registering. Click on "compiler", register, and download the installer (8.7 MB). After installing, add C:\Borland\BCC55\bin to your PATH and create the file C:\Borland\BCC55\bcc32.cfg exactly as shown below:

-I"c:\Borland\Bcc55\include"
-L"c:\Borland\Bcc55\lib"

There are also commercial compilers such as Microsoft Visual Studio and Intel C++. Many commercial compilers include an integrated develop environment (IDE) with a graphical user interface, editor, debugger, extra libraries, and other tools. These are beyond the scope of this document.

Compiling C++ Programs

g++, Borland 5.5 and Mars are command line compilers. You write programs with a text editor (such as Notepad) and compile them using commands from a UNIX/Linux shell or a Windows command window. The output of a compiler is an executable program that you also run from a shell or command window. To open a command window in Windows, click Start/Run and type "cmd".

Create a text file with a .cpp extension, e.g. hello.cpp, e.g.

  #include <iostream>
  using namespace std;
  int main()
  {
    cout << "Hello world\n";
    return 0;
  }

In Windows, compile as follows (producing hello.exe):

  MinGW:   g++ hello.cpp -o hello.exe
  Borland: bcc32 hello.cpp
  Mars:    dmc hello.cpp -IC:\dm\stlport\stlport
  To run:  hello
To compile and run in Unix or Linux:
  g++ hello.cpp -o hello
  ./hello
Useful g++ options (other compilers will differ):
  -o file    (rename output file, default is a.out in UNIX/Linux or a.exe in Windows)
  -O         (Optimize, compiles slower but runs faster)
  -Wall      (Display all warnings)
  -s         (Strip debugging info from executable to make it smaller)
  --help     (List all available options)

Program Structure

A C++ program has the following structure:
  // Standard library headers, include as needed
  #include <iostream>  // cin, cout (standard input/output)
  #include <fstream>   // ifstream, ofstream (files)
  #include <string>    // string (sequence of characters)
  #include <vector>    // vector (an array with stack operations)
  #include <map>       // map (associative array)
  #include <algorithm> // min(), max(), swap(), sort(), copy(), fill()
  #include <cstdlib>   // rand(), abs(), atoi(), exit()
  #include <cctype>    // isalpha(), isdigit(), tolower()
  #include <cmath>     // pow(), log(), exp(), sqrt(), sin(), cos(), atan()
  #include <ctime>     // time()

  using namespace std; // Required if any headers are present

  // Global type, object, and function declarations...

  int main() {         // Execution starts here
    // Statements and local type and object declarations...
    return 0;          // Execution ends here
  }
For example:
  // hello.cpp - prints "Hello" and a newline character to the screen
  #include <iostream>     // Defines object cout (standard output)
  #include <string>       // Defines type string
  using namespace std;    // Always after the last header
  int main() {            // There must be one function main() returning int
    string s="Hello\n";   // Declaration: create object s of type string
    cout << s;            // Statement: output s
    return 0;             // main()'s return value actually doesn't matter
  }                       // End of main()

The // symbol indicates a comment to the end of the line. It is used to document the program, and is ignored by the compiler. You can also use /* ... */ for multiline comments.

Declarations

Objects and types can be declared globally, or local to a function or {block}. Functions can only be declared globally, not inside another function. The syntax of an object declaration is a type name followed by a list of objects to be created (with possible initialization), and ending with a semicolon. The following examples declare objects of the most common types.

  // Declaring objects of existing types (global or local)
  int i, j=3;              // Integers, i's initial value is undefined
  double x=3.5, y=j;       // Real numbers, y is 3.0
  bool t=false, u=true;    // Logical e.g. if (t && u) {...}
  string s, hi="hello";    // s is initially an empty string, ""           in <string>
  char c='a', c2=hi[1];    // Character, c2 is 'e'
  vector<int> a(5);        // Array a[0] through a[4] of int               in <vector>
  map<string, int> m;      // Associative array, e.g. m["hi"]=5;           in <map>
  ifstream in("file.txt"); // Input file e.g. while (getline(in, s)) {...} in <fstream>
  ofstream out(s.c_str()); // Output file e.g. out << "hello\n";           in <fstream>
  const double PI=3.14159; // Not a variable, e.g. PI=4; is an error

  // Functions (must be global)
  int sum(int a, int b) {return a+b;}  // e.g. i=sum(j, 2); sets i=5
  void swap(int& a, int& b) {          // Pass by reference, no return value
    int tmp=a; a=b; b=tmp;             // e.g. swap(i, j); must be variables
  }                                    // Scope of a, b, and tmp ends here, implied return;
  void print(const string& s) {cout << s;}  // Pass large objects by const reference

  // Declaring new types (global or local)
  typedef double Real;     // Real z; declares object z of type double
  struct Complex {         // Complex a; declares a.re, a.im type double
    Real re, im;           // Data members
    Complex(double r=0, double i=0) {re=r; im=i;} // Initialization code
  };
Objects, types, and functions may be given names using letters, digits, and underscores, and starting with a letter. C++ is case sensitive. Thus, x_3 and X_3 are two different names. Normally, we use lower case, except that new type names are usually Capitalized and global constants are often UPPER CASE.

Initialization is optional for all types. For the built in types int, double, bool, and char, the initial value is undefined, so initialization is recommended. For the library types string, vector, and map (those that require a header), the initial value is empty. For a vector or map of built in types, the elements are initially 0 or false.

Statements

A statement is either a control statement like if, while, for, return, break, or an expression. For example, the following are expressions.

  cin >> s;               // Input, read one word into s
  s = "Hello, " + s;      // Concatenation and assignment
  cout << s << '\n';      // Output s and a newline
Control statements have the following general forms.
  if (t) {...}            // If t is true, execute the block
  else if (t) {...}       // May appear 0 or more times
  else {...}              // May appear 0 or 1 times

  while (t) {...}         // Repeat the block 0 or more times while t is true

  do {...} while (t);     // Repeat the block 1 or more times while t is true

  for (d; t; s) {...}     // Equivalent to: d; while (t) {... s;}

  break;                  // Jump out of a while or for loop

  return x;               // Return from a function with value x
A block {...} may contain 0 or more statements and declarations (which are local to the block). If there is only one statement, then the braces may be omitted.
  if (s=="hello")         // Compare strings (case sensitive)
    cout << "hi";         // If true
  else
    cout << "bye";        // If false
break exits a loop. For instance, the following reads from the keyboard until the user types "bye"
  while (true) {          // Loop forever?
    string s;             // Local declaration
    cin >> s;             // Input a word
    if (s=="bye")
      break;
  }                       // Scope of s ends here
  cout << s;              // Error, undefined object s
A for loop is normally used to iterate through a sequence. The first statement may declare an object which is local to the loop.
  for (int i=0; i<5; ++i)    // Loop 5 times, ++i means i+=1 or i=i+1
    cout << i << ' ';        // Prints 0 1 2 3 4
  cout << i;                 // Error, undefined object i

Expressions

An expression uses operators or functions on objects to change the value of some object or do input or output. When an expression has more than one operator (e.g. a=b+c) the operator with the highest precedence is evaluated first (e.g. + before =, thus a=(b+c)). The precedence order from highest to lowest is:
  x[i] f(...) T(x) x.m p->m     Index, function call, conversion, struct/iterator member
  -x !x ++x --x *p              Unary: Minus, not, increment, decrement, iterator contents
  x*y x/y x%y                   Multiply, divide, mod
  x+y x-y                       Add or concatenate, subtract
  cin>>x cout<<x;               Input, output
  x<y x<=y x>y x>=y             Comparison (less than, or equal, greater than, or equal)
  x==y x!=y                     Comparison (equals, not equal)
  t&&u                          And then
  t||u                          Or else
  x=y x+=y x-=y x*=y x/=y x%=y  Assignment combined with arithmetic, e.g. x+=y means x=x+y
Operators of equal precedence are evaluated left to right except for unary operators and assignment.
  a-b-c;                      // (a-b)-c
  a=b=0;                      // a=(b=0), assigns 0 to b, then b to a
  f()[i]                      // i'th element of string/vector/map returned by f()
Assignment may be combined with arithmetic operators. Assignments return the object assigned to. The left side of an assignment must be a variable (or lvalue). It cannot be an expression, a const, or an ifstream, ofstream, or cin, cout, or cerr.
  a*=b;                       // a=a*b;
  (a+=b)+=c;                  // a=a+b+c;
  a+b=c;                      // Error, assignment to expression
Increment and decrement operators add or subtract 1 and return the new value. There is also a postfix form that returns the original value.
  int a = 5, b = ++a;         // Prefix, a=6; b=6;
  cout << b--;                // Postfix, b=5, prints 6
Expressions are loosely typed, with conversions occurring as needed. A conversion may also be made explicit by using the notation T(x) or (T)x to convert x to type T.
  double(3)/2                 // 1.5, explicit double(3), implicit double(2)
The meaning of most other operators depend on the type of the operands as described below. The notation <header> means that to use the features described, your program must have
  #include <header>

int

An int is an integer number written without a decimal point, e.g. 35. Valid operators are:
  Arithmetic, returns int: + - * / % -x ++ --
  Comparison, returns bool: == != < <= > >=
Division rounds toward 0, e.g. 5/3 is 1, -5/3 is -1. % is the remainder, e.g. -5%3 is -2. Division or mod by 0 is a run time error.

On most machines, an int can only represent 32 bit signed integers, i.e. from -231 = -2147483648 to 231-1 = 2147483647. If a result is outside this range (e.g. 1000000*1000000) then the result is reduced modulo 232.

bool

A bool is true or false. Operators:
  !t        // not t
  t&&u      // t and then u, true if both t and u are true
  t||u      // t or else u, true if either t or u is true
  bool(x)   // true if int x is not 0
  bool(cin) // true if last input was successful
  int(t)    // 1 if true, 0 if false
The && and || operators do not evaluate the right operand unless necessary, e.g. (j!=0 && i/j > 1) cannot cause a division by 0 error.

A test condition in an if, for or while loop implicitly converts an expression to bool.

  while (cin >> s)  // Loop until input fails
  if (i=3)          // Legal but probably wrong, = means assignment, returns bool(3) or true

double

A double is a real number written with a decimal point, e.g. 35.0 or 3.14159, or in scientific notation, e.g. 1.5e-4 == 0.00015. Valid operators are:
  Arithmetic: returns double: + - * / -x (not % ++ --)
  Comparison: < >
  Conversion: int(x) rounds toward 0, double(i) does not change the value
An expression mixing int and double is double, e.g. 5/4 is 1 but 5.0/4 or 5/4.0 is 1.25. Comparison using == and != are not meaningful because of round off error, e.g. 0.1*10==1 is false (differing by about 10-14) because 0.1 does not have an exact representation as a binary fraction.

The header <cmath> defines mathematical functions taking int or double and returning double.

  sin(x); cos(x); tan(x);   // Trig functions, x in radians
  asin(x); acos(x); atan(x);// Inverses
  atan2(y, x);              // atan(y/x)
  sinh(x); cosh(x); tanh(x);// Hyperbolic
  exp(x); log(x); log10(x); // e to the x, log base e, log base 10
  pow(x, y); sqrt(x);       // x to the y, square root
  ceil(x); floor(x);        // Round up or down (as a double)
  fabs(x); fmod(x, y);      // Absolute value, x mod y

On most machines the valid range of a double is about -1.7e308 (-1.7 * 10308) to 1.7e308 with about 14 significant digits of precision.

char

A char is normally a one byte (8 bit) signed number from -128 to 127. Operations are the same as for int, with the exception of input and output, which are as characters. The conversion between character and number is defined by the ASCII code. The following code is possible because 0-9, A-Z, and a-z occur in 3 contiguous sequences.
  // Convert UPPER CASE input to lower case output
  char c;
  while (in.get(c)) {          // Read c, loop while successful
    if (c >= 'A' && c <= 'Z')  // if (isupper(c))
      c += 'a' - 'A';          //   c = tolower(c) (or c += 32)
    cout << c;                 // Print c as a character
  }
  cout << 'a' - 'A';           // Print 32 (not a space, arithmetic always results in an int)
  cout << char(32);            // Print a space (convert int to char modulo 256)
Characters are written enclosed in single quotes. Some special characters may be escaped with a \
  'a'     // lowercase a
  ' '     // space
  '\n'    // newline
  '\r'    // carriage return
  '\t'    // tab
  '\\'    // backslash
  '\''    // single quote
  '\"'    // double quote
  '\x7F'  // ASCII code in hexadecimal '\x00' to '\xFF'
The header <cctype> defines character tests and conversion functions.
  isalnum(c);                  // Is c a letter or digit?
  isalpha(c); isdigit(c);      // Is c a letter?  Digit?
  islower(c); isupper(c);      // Is c lower case?  Upper case?
  c=tolower(c); c=toupper(c);  // Convert c to lower/upper case

<string>

A string, s, is a sequence of characters. Valid operations are:
  Comparison: == != < <= > >=
  Concatenation: s+s s+=s
  Substring: s.substr(i,j), s.substr(i)
  Length: int(s.size())
  Index: s[i] where i is 0 to int(s.size())-1
  Input: cin >> s; getline(cin, s);
  Output: cout << s;
Comparison is case sensitive, and is done by comparing the ASCII codes of the first nonmatching characters, i.e. "A" and "a" are different. Either operand, but not both, may be a literal.
  string s="cat";
  s > "Cat";            // true, lower case comes after upper case
  "cat" == "cat"        // false, comparing literals is not meaningful
  s += "alog"           // "catalog"
  "cat" + "alog"        // Error, one operand must be a string
s.substr(i,j) returns a substring of size j (or to the end if omitted) after skipping the first i characters.
  string s="abcdefg";
  s.substr(3, 2);       // "de"
  s.substr(3);          // "defg"
s.size() is an unsigned type, which can lead to errors in expressions involving negative numbers. Therefore, it should always be converted to int.
  s.size() > -1         // false!  -1 is silently converted to a huge unsigned number
  int(s.size()) > -1    // true
The elements of a string have type char and may be assigned to. There is no run time checking of array bounds.
  string s="hello";
  s[0]='j';             // "jello"
  char c=s[4];          // 'o'
  s[5]=s[-1];           // Program may crash

<iostream>

This header defines the global objects cin, cout, and cerr representing standard input, standard output, and standard error. Normally cin is the keyboard, and cout and cerr are the screen. cin and cout, but not cerr, may be redirected to a file or pipe in UNIX and Windows.
  ./a.out <file1 >file2
causes the program a.out to read from file1 through cin and to create and write to file2 through cout. Writing to cerr still goes to the screen, and is useful for printing error messages that you want the user to see. cout and cerr support the same operations:
  cout << x;             // Write int, double, bool, char, or string to standard output
  cerr << x;             // Write to standard error
  cout << x << y;        // Write more than one object.
  cin.get(c);            // Read char c (including '\n'), true if successful
  c=cin.get();           // Read char c as an int, or EOF (-1) if there is no more input
  getline(cin, s);       // Read a line into string s (discarding '\n'), true if successful
  cin >> s;              // Read one word delimited by spaces or newlines
Input operations return cin, which converts to false at end of file.
  while (cin.get(c)) cout << c;  // Copy input to output one char at a time
  while (getline(cin, s)) cout << s << "\n";  // Copy one line at a time

<fstream>

An ifstream is an input file and behaves identical to cin. An ofstream is an output file and behaves identical to cout. The file is open while the stream is in scope. The stream can be tested like cin to determine if the open succeeded. Opening an ofstream erases the previous contents of the file and creates a new one. The file name must be a literal or converted to one using s.c_str().
  // Copy inputfile to outputfile
  string inputfile="input.txt", outputfile="output.txt";
  ifstream in(inputfile.c_str());   // Might fail, file not found
  ofstream out(outputfile.c_str()); // Might fail, permission denied or bad path
  if (!in)
    cerr << inputfile << " not found\n";
  if (!out)
    cerr << outputfile << " not created\n";
  char c;
  while (out && in.get(c))  // copy until disk full or end of input
    out << c;

In Windows, text files normally end in a carriage return and linefeed ("\r\n"), but in UNIX and Linux, the carriage return is omitted. To maintain text file compatibility, when a linefeed ("\n") is output, it is converted to "\r\n". When "\r\n" is input, the "\r" is discarded. To prevent this conversion, open a file in binary mode:

  ifstream in(inputfile.c_str(), ios::in | ios::binary);
  ofstream out(outputfile.c_str(), ios::out | ios::binary);
cin, cout and cerr are always in text mode.

<vector>

A vector is an array of elements of type T which can be resized.
  vector<T> v(n);          // n elements of type T
  int(v.size())            // n
  v[i]                     // i'th element, 0 <= i < n
  v.push_back(x)           // Increase size by 1 and append x
  v.resize(n)              // Change size to n
  vector<T> v;             // Size defaults to 0
  == != < <= > >=          // Comparison
T is the type of the element. If T is numeric, the initial values are 0. If string, then "". Indexing is not bounds checked. Comparison is by the first nonmatching element.
  // Read lines of input and print them in reverse order
  vector<string> v;
  string s;
  while (getline(cin, s))
    v.push_back(s);
  for (int i=int(v.size())-1; i>=0; --i)
    cout << v[i] << "\n";

<map>

A map associates a value of type V with a unique key of type K. It generalizes the idea of a vector by not restricting the keys to be type int.
  map<K,V> m;               // Map, initially empty
  m[k]=v;                   // Associate v (type V) with key k (type K)
  m[k]                      // v
  int(m.size())             // Number of unique keys
To retrieve a sorted list of stored keys, we use iterators. An iterator points to one key-value pair in the map.
  map<K,V>::iterator p;     // Pointer to a key-value pair
  p=m.begin()               // Points to first pair sorted by key
  p=m.end()                 // Points 1 past the last pair
  ++p;                      // Point to next pair
  --p;                      // Point to previous pair
  p==q p!=q                 // true if they point to same/different pairs
  p->first                  // key
  p->second                 // value, may be assigned to
  map<K,V>::const_iterator p;  // Like iterator, but you can't change the value
The following sorts a text file using a map<string, int>. It associates each line in the file (the key) with the number of times it occurs. The sorted keys are then printed the number of times indicated by the value.
  map<string, int> m;
  string s;
  while (getline(cin, s))
    ++m[s];
  for (map<string, int>::const_iterator p=m.begin(); p!=m.end(); ++p)
    for (int i=0; i<p->second; ++i)
      cout << p->first << '\n';
If you want to retrieve m[k] and don't know if k was referenced, and you don't want to increase the map size if it wasn't, use m.find(k).
  p=m.find(k);                // m.end() if not found
  if (p!=m.end()) p->second;  // Value
  m.erase(p);                 // Remove pair, also m.erase(k)

<algorithm>

  min(x,y)                             // Smaller of x or y
  max(x,y)                             // Larger of x or y
  swap(x,y);                           // Exchange the values of x and y
  sort(v.begin(), v.end());            // Sort a vector or string (but not a map)
  copy(v.begin(), v.end(), d.begin()); // Copy v to d, d.size() >= v.size()
  fill(v.begin(), v.end(), x);         // Set all elements of v to x
You can specify a slice of a vector or string by adding to begin() or subtracting from end().
  sort(v.begin()+1, v.end()-1);        // Sort all but first and last element
  copy(v.begin(), v.begin()+v.size()/2, v.begin()+v.size()/2);  // Copy first half to second

By default, sort() orders elements using <. You can specify your own order by passing a function that compares two elements and returns true if the first is less than the second. Use stable_sort() to preserve the order of equal elements. The following groups even numbers before odd in a vector<int> v

  bool evenFirst(int a, int b) {  // true if a is even and b is odd
    return a%2==0 && b%2==1;
  }
  // ...
  stable_sort(v.begin(), v.end(), evenFirst);

No run time checking is done that a valid range of elements is specified. In particular, copy() does not check if the destination is large enough to hold the result. The program may crash if not. Specifying a slice with negative size can also be disaster.

  vector<int> v(10), d;
  fill(v.begin()-1, v.end()+1, 0);      // Crash, writes off ends of v
  fill(v.end(), v.begin(), 0);          // Crash, negative size
  copy(v.begin(), v.end(), d.begin());  // Crash, d.size() is 0

<cstdlib>

  atoi(s.c_str())           // Convert string to int, e.g. atoi("35") is 35
  atof(s.c_str())           // Convert string to double, e.g. atof("35") is 35.0
  abs(i)                    // Absolute value of int i
  rand()                    // Pseudo-random int from 0 to RAND_MAX (at least 32767)
  srand(n)                  // Initialize rand(), e.g. srand(time(0));
  system(s.c_str())         // Execute OS command s, e.g. system("ls");
  if (getenv(s.c_str)) s=getenv(s.c_str())  // Environment variable e.g. getenv("PATH")
  exit(n);                  // Kill program, return status n, e.g. exit(0);

<ctime>

  double(clock())/CLOCKS_PER_SEC   // Time in seconds since program started
  time(0)                          // Time in seconds, usually since Jan. 1, 1970

Arrays

An array is like a vector, but its size is fixed at compile time. However, arrays can be initialized and can have more than one dimension. The only valid operation on array x is x[i] where i ranges from 0 to the size - 1. After a partial initialization, the rest of the elements are 0. However if there is no initialization, the elements are random. Array bounds are not checked.

  int a[5] = {3,10,15,20,0};              // a[0] is 5, a[4] is 0
  int b[2][3] = {{10,20,30},{40,50,60}};  // array of 2 arrays, b[1][2] is 60
  int c[1000] = {3};                      // c[1]...c[999] are all 0
  int d[1000];                            // d[0]...d[999] are random
Arrays have no .size(), .begin() or .end(). To sort, use the array name for .begin() and add the size to get the end.
  sort(a, a+5);                    // {0,3,10,15,20}
  stable_sort(a, a+5, evenFirst);  // {10,20,0,3,15}
A quoted literal string is actually an array of char with a (nonprinting) zero byte to mark the end. There is an automatic conversion to string, which removes the zero byte. The reverse conversion is done with .c_str().
  char e[4] = "dog";          // same as char e[4]={'d','o','g',0};
  string s=e;                 // value is "abc", int(s.size()) is 3
  cout << int(s.c_str()[3]);  // 0
Note that 'a' (char) and "a" (array of char) are different types, and both are distinct from string.

Functions

Every program has a function called int main() taking no parameters and returning int. Unlike objects, which can be local or global, all functions are global. They cannot be defined within another function or block. The general form is:
  T f(T1 x1, T2 x2, ... ) {...}
where f is the name of the function, T is the return type, and x1, x2, ... is a list of 0 or more parameters with types T1, T2, ... When the function is called, the local declarations and statements in the block are executed. The last statement executed must return an expression of type T. For instance:
  #include <iostream>
  using namespace std;
  int division_error=0;       // Global object, visible from here on
  int divide(int x, int y) {  // Global function, visible from here on
    if (y==0)
      return division_error;
    else
      return x/y;
  }                           // Scope of x and y ends here
  int main() {
    division_error = -1;
    cout << divide(7+1, 2) << "\n";   // Print 4
    return 0;
  }

A function may return void, in which case it does not need to execute a return statement. It returns when the closing brace is reached. Function parameters may be passed one of three ways:

T x,
Pass by value, x is a local copy initialized by the argument expression. Assigning to x changes only the local copy, which is discarded when the function returns. The argument may be implicitly converted if the type differs. x should be small: int, double, bool, char, iterator.
T& x,
Pass by reference. Assigning to x changes the argument, which must be a variable, not a constant or an expression. The type must match exactly.
const T& x,
Pass by const reference. To the caller it looks like pass by value (expressions, const, and implicit conversions allowed), but no local copy is made, so it is more efficient. Thus, large objects such as strings, vectors, maps, and structs should be passed this way. The function cannot modify x.
  void assign(bool t, string& dest, const string& src) {  // value, ref, const ref
    if (t)
      dest=src;
  }
  int main() {
    assign(true, "hi", "ho");  // Error, dest refers to a constant expression
Function names may be overloaded (reused) as long as they can be distinguished by the types of their parameters.
  void swap(int& a, int& b) {...}
  void swap(string& a, string& b) {...}
  int main() {
    int i=1, j=2;
    swap(i, j);  // Calls the first swap()
To pass an array of T to a function, declare the parameter as type T*, or as const T* if the elements will not be changed. This has the effect of passing by reference or const reference. Note that the function will not know the size of the array.
  // print msg, then sort n elements of a
  void sortArray(const char* msg, int* a, int n) {
    cout << msg << "\n";  // assumes msg ends in a zero byte
    sort(a, a+n);
  }

  int main() {
    int x[5]={6,2,4,3,8};
    sortArray("sorting...", x, 5);
Command line arguments may be passed to main by giving it parameters (int argc, char** argv), where argv is an array of argc arrays of char, each containing one word from the command line. For example, if echo.cpp is:
  #include <iostream>
  using namespace std;
  int main(int argc, char** argv) {
    for (int i=0; i<argc; ++i)
      cout << argv[i] << '\n';
    return 0;
  }

  g++ echo.cpp
  ./a.out hello world
  ./a.out
  hello
  world

struct

A struct declares a new type whose instances (objects) consist of collections of other objects. The type may be declared anywhere that an object can be declared. The type name follows the same scope rules. The members of a struct are accessed in the form object.member. A struct is declared:
  struct T {                  // Creates T as a new type
    // declarations (without initialization)
  };
By convention, new type names are capitalized. For example:
  struct Person {             // Person is a new type
    string name;              // a data member
    int age;                  // another member
  };
  Person x;                   // x is an object, x.name is "", x.age is not not initialized
  Person y = {"Joe", 25};     // y.name is "Joe", y.age is 25
  x = y;                      // Assigns x.name = y.name, x.age = y.age
  if (x == y)                 // Error, comparison is not supported
  vector<Person> v(5);        // vector of 5 Persons, not initialized
  v[4].age = 10;              // assign to member of object v[4]

class

A class is a struct with member functions. A class is divided into a public section, whose members can be accessed as in a struct, and a private section, whose members can be accessed only by the member functions. Member functions are declared in the class like ordinary functions but are called as object.function().

A special member function called a constructor initializes objects of the class. It is not called directly, but rather by passing arguments in the declaration of the object. A constructor has the same name as the class and no return type.

  class Person {
  private:
    string name;
    int age;
  public:
    void setName(const string& n) {name=n;}          // member function
    string getName() const {return name;}            // const member function won't modify members
    Person(const string& n, int a) {name=n; age=a;}  // constructor
  };

  Person x("Joe", 25");      // Calls constructor with n="Joe", a=25
  Person y;                  // Error, constructor requires two arguments
  Person y = x;              // OK, copy
  y = x;                     // Assignment
  y.name = "Bob";            // Error, name is private
  y.setName("Bob");          // OK, setName() is public
  cout << x.age;             // Error, age is private
A member function may be declared const (as in getName()) to indicate it does not modify any data members. Only const member functions can be called on const objects (including objects passed by const reference).
  const Person c = x;        // Initialization of const object c (or by constructor is OK)
  c = x;                     // Error, assignment to const
  c.setname("Alice");        // Error, setName() is not const
  cout << c.getName();       // OK, getName() is const
It is normal in good object oriented design to make all data members private, and only make public enough member functions to make the object usable (including constructors). Member functions that don't modify data members should always be const.

Also, the code for member functions should be moved outside the class unless the code is very short as in this example. Otherwise the compiler takes the inlined code as an optimization hint to replace the function call with inlined code, which increases the size of the executable. The code can be separated by replacing the {...} with ; and writing the function again in the form class::function

  class Person {
  public:
    void setName(const string& n);
    string getName() const;
    Person(const string& n, int a);
  private:
    string name;
    int age;
  };

  void Person::setName(const string& n) {
    name=n;
  }

  string Person::getName() const {  // Note const is repeated
    return name;
  }

  Person::Person(const string& n, int a) {  // constructor
    name=n;
    age=a;
  }