LevSelector.com New York
home > C++
C++ Tutorial #2 Other pages

- intro - preparing for the interview
- first C++ programs
- data types
- pointers & references
- structures and arrays
- logic, if-else, for, while, switch
- functions
- strings
- text files
- binary files , random access files
- command line arguments
- Linked List example
- Recursion example
- functions with variable number of arguments
- splitting program into many files
- misc

- OOP, classes, constructors, destructor
- exceptions
- friend, nested, static, namespace
- operator overloading
- abstract class, parent-child hierarchy
- private, protected, public (inheritance & encapsulation)
- virtual functions
- templates
- Programming with STL
- - - 

- C
- C++
- C++ tutorial #1
- threads and multi-processing

intro - preparing for the interview

If you want to pick up C++ fast, here is a possible plan:

first C++ programs  home - top of the page -

Some of the examples in this tutorial are original, others are inspired or derived from www.cprogramming.com/tutorial.html ,  from "The Beginner's Guide to C++" by Oleg Yaroshenko, (BTW, this is a very VERY good book for a beginner), and other sources.
Also good place is the C/C++ reference: cppreference.com.

1st program
// file hello.cpp
#include <iostream>

main() {
   std::cout<<"Hello" << std::endl;
}

or to avoid typing "std::" every time:
// file hello.cpp
#include <iostream>
using namespace std;

main() {
   cout<<"Hello" << endl;
}

2nd program
// file hello2.cpp
#include <iostream>
using namespace std;

 const int ii = 5; // const will not allow to change it

 int main() {
   int n;
   cout<<"Hello" << ii << "Dear" 
              "Friend" << endl;
   cout<<"Please\nPlease enter a number: ";
   cin>> n;
   cout<<"You entered: "<< n <<endl;
   cout<<"Squared:   "<< n*n <<endl;
   return 0;
 }

To compile and run on Linux:

c++   -o   a  hello.cpp
a
hello

On linux there is a main compiler/linker called "gcc" and 2 scripts (today they are executables) called c++ and g++ (they are usually the same). The c++ inside calls gcc with default options and libraries ( -l stdc++ ). So you can cmpile your test as following:

gcc -l stdc++ -o   a  hello.cpp

On other unixes (Solaris, for example) one can run gcc, or use other compilers (Sun has its own compiler).

On Windows people ususally use Microsoft Visual Studio - just google it and download 3-month free installation. You can also install cygwin - and run unix-like gcc. Or there are some other options:

http://www.mingw.org/ -> gcc for windows
http://www.bloodshed.net/devcpp.html - Bloodshed Dev-C++ is a full-featured IDE for the C/C++ - uses Mingw port of GCC.
http://www.eclipse.org/downloads/ -> eclipse IDE does c++
http://netbeans.org/features/cpp/index.html -> netbeans IDE does c++
http://www.embarcadero.com/products/cbuilder - CodeGear - Borland C++ builder aquired in 2008 by Embarcadero

Yet another option - download free compiler from http://www.borland .com. For version 5.5 it installs into C:\Borland\Bcc55.
Add to path:  C:\Borland\Bcc55;C:\Borland\Bcc55\bin
Create 2 cfg files in C:\Borland\Bcc55\bin as advised in the readme file.
now you can compile from command prompt:

bcc32.exe hello.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
hello.cpp:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

hello.exe
Hello

#define
#include <iostream.h>
#define MAMA "mama" <<endl; 

main() {
  cout<<MAMA 
}

C++ inherits all standard operators from C, for example:
++a;    and   a++;
a + = 2;
a - = 2;
a* = 4;
a* = 5;

data types home - top of the page -

data types:
int, char, long int, float, double, long double,
bool - boolean (2 values: true and false - same as 1 and 0)
cout << sizeof (char); // to show the size in memory
unsigned modifier
#include <iostream.h>
main() {
cout << "sizeof(int) : " << sizeof(int) << endl;
cout << "sizeof(char) : " << sizeof(char) << endl;
cout << "sizeof(long) : " << sizeof(long) << endl;
cout << "sizeof(float) : " << sizeof(float) << endl;
cout << "sizeof(double) : " << sizeof(double) << endl;
cout << "sizeof(long double) : " << sizeof(long double) << endl;
}

auto var1 = 1; // int
auto var2 = 1.0; // double

int var1;
decltype(var1) var2; // declare var2 to be of the same type as var1

Enumerated types: 
enum weekDay {Sunday=1, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
  // Monday will be 2, Tuesday - 3, etc.

weekDay myDay = Monday;
// ...
if (myDay != Sunday && myDay != Saturday)
   myDay = Saturday;

Define your own types using the "typedef" statement: 
typedef  int  weekDays[7];
main() {
  weekDays theDays; // array of 7 elements
  // ...
}

Type casting: 
#include <iostream.h> 
int main() {
  cout<<(char)65; 
     // The (char) is a typecast, telling the computer to interpret the 65 as a
     // character, not as a number.  It is going to give the ASCII output of 
     // the equivalent of the number 65(It should be the letter A).
  return 0;
}

#include <iostream.h>
int main() {
  for(int x=0; x<256; x++) { //The ASCII character set is from 0 to 255
    cout<<x<<". "<<(char)x<<" ";
    if(x%12 == 11) cout << "\n";
  }
  return 0;
}

//-- 2 forms of typecasting:
char cc='A';
int i1 = (int) cc;
int i2 = int(cc);

pointers and references home - top of the page -

pointers
#include <iostream.h>
int main() { 
 int x;              //A normal integer 
 int *pointer;    //A pointer to an integer 
 pointer=&x;      //Read it, "pointer equals the address of x"
 cin>>x;          //Reads in x 
 cout<<*pointer; //Note the use of the * to output the actual number stored in x
 return 0;

Three ways:
int*   a;
int   *a;
int  *  a;

Reference = alias (shortcut) 
int A = 0;
int & rA = A;    // rA is reference - and we initialized it to be an alias for A

rA = 1;    // now rA == 1, which means that A == 1 too.
A=2;    // now rA == 2 too

int * prA = &rA;    // &rA is same as &A
(*prA)++;    // same as A++ or rA++, now they are == 3

int & rrA = rA;    // one more alias for A
rrA++;    // now they all == 4

const int & crA = A;    // one more alias
A++;    // now they all == 5 (even crA !!   But you can't do crA++;)

Pointers to functions:
void ff(int a, char b); // function itself
void (*ptf)(int a, char b); // pointer to a function
void (*afp[10])(int a, char b); // array of function pointers

// initializing the pointer and  invoking the function
    ptf = ff;
    (*ptf)(5,'A');

// same for the array of pointers to functions:
    afp[3] = ff;
    (*atf)(5,'A');

Far pointers:
int* _far pnum1 = %num1;  // windows

Pointers to objects:
 
class myClass {
  // some definitions here
}

myClass obj1; // object of the type of this class
myClass pobj1 = &obj1; // pointer to this object
pobj1->myfunc(1,2); // calling a method 

Pointers to pointers:
int** pp;
 
 

structures and arrays home - top of the page -

structures
#include <iostream.h>

// define structure type
struct xampl {
  char Name[21];
  int  Height;
};

int main() { 
  xampl structure = {12,"Kolya"};  // initialize the structure of type "xampl"
  xampl *ptr;

  structure.Height=12;    // another way to initialize
  structure.Name="Kolya";    // another way to initialize

  ptr=&structure;  // pointer to the structure
  cout<<ptr->Name << " - " << ptr->Height; // note the  ->  notation
  return 0;
}

In C++ you can copy structured variables by assigning them (or passing/returning them into/from a function).
if A,B - structures, and you do one of those:
     A = B
     *pA = *pB
Then actual shallow copying of a structure members will happen (shallow means that targets of pointer members will not be followed and copied).
Same shallow copying will happen if we pass the structure to a function. All this is demonstrated in the text below (it is written in C-style and works in both C and C++) :
 
#include <stdio.h>

struct TT { int a; int b; }; 
struct TT A,B, *pA, *pB;

void showA(void) { printf("  A.a=%d A.b=%d\n",A.a,A.b); } 
void showB(void) { printf("  B.a=%d B.b=%d\n",B.a,B.b); } 

void val(struct TT s) { 
  s.a=5; s.b=6;
  printf("inside function\n  s.a=%d s.b=%d\n",s.a,s.b);

void pt(struct TT *s) { 
  (*s).a=5; (*s).b=6;
  printf("inside function\n  (*s).a=%d (*s).b=%d\n",(*s).a,(*s).b);

main () {
  A.a=1, A.b=2; B.a=0, B.b=0; pA = &A, pB = &B;
  printf("\n");
  printf("initially:\n"); showA(); showB();

  printf("B=A:\n"); B = A; showB(); 
  printf("reset B:\n"); B.a = 0; B.b = 0; showA(); showB(); 

  printf("*pB=*pA:\n"); *pB = *pA; showB();
  printf("reset B:\n"); B.a = 0; B.b = 0; showA(); showB(); 

  printf("\npassing struct into a function makes a shallow copy\n");
  printf("  val(B)\n"); val(B); printf("outside function\n"); showB(); 
  printf("\npassing struct into a function by pointer\n");
  printf("  pt(&B)\n"); pt(&B); printf("outside function\n"); showB(); 
  printf("\n");
}

Output:

initially:
  A.a=1 A.b=2
  B.a=0 B.b=0
B=A:
  B.a=1 B.b=2
reset B:
  A.a=1 A.b=2
  B.a=0 B.b=0
*pB=*pA:
  B.a=1 B.b=2
reset B:
  A.a=1 A.b=2
  B.a=0 B.b=0

passing struct into a function makes a shallow copy
  val(B)
inside function
  s.a=5 s.b=6
outside function
  B.a=0 B.b=0

passing struct into a function by pointer
  pt(&B)
inside function
  (*s).a=5 (*s).b=6
outside function
  B.a=5 B.b=6

arrays
#include <iostream.h>

int main() {
  int ia[3] = { 3,4,5 };  // initialize array 
  cout << sizeof ia << "/" << sizeof ia[0] << "="
         << sizeof ia / sizeof ia[0]  << endl;

int grid[3][3] = { { 1,2,3 }, { 1,2,3 }, { 1,2,3 } }; // initialize 2-dim array

  int x, y, anarray[8][8];//declares an array like a chessboard
  for(x=0; x<8; x++) {
    for(y=0; y<8; y++) {
      anarray[x][y]=0;
    }
  }

  for(x=0; x<8;x++) {
    for(y=0; y<8; y++) {
cout<<"anarray["<<x<<"]["<<y<<"]="<<anarray[x][y]<<" ";//you'll see
    } 
  }

 return 0;
}

*a + 1;  // take value at addr. pointed by a - and increase the value by 1
*(a+1);  // shift the address by the size of one data element (2 bytes for int) - and take the value there.
 
 #include <iostream.h>
 int arr[4] = {1,2,3,4};
 int *pp;
 main () {
   pp = arr;
   cout << "Hello" << endl;
   cout << "arr[2] = " << arr[2] << " = " << *(pp+2)
                                 << " = " << *(arr+2) << endl;
   cout <<  sizeof(arr)/sizeof(arr[0]);
   cout << endl;
 }

One thing that arrays don't require that other variables do, is a reference operator.
Example: a pointer to the string :
char *ptr;
char str[40];
ptr=str; //gives the memory address without a reference operator(&)

//As opposed to

int *ptr;
int num;
ptr=&num;//Requires & to give the memory address to the ptr

Dynamic arrays:
  create and destroy using new and delete [] operators:
 
#include <iostream.h>
#include <stdio.h>   // to use printf( )

void main(void) {
  int *parr = new int[10];
  for (int ii=0;ii<10;ii++) parr[ii]=ii*ii;
  for (int ii=0;ii<10;ii++) printf("%d - %d\n",ii,parr[ii]);
  delete [] parr;
}

logic, if-else, for, while, switch home - top of the page -

logic
 #include <iostream.h>
main () {
  cout << ( 0 < 2 );   // 1
  cout << (2 != 2 );   // 0
  cout <<  !(1 || 0);   //  0 
  cout <<  !(1 || 1 && 0);   // 0 (AND is evaluated before OR)
  cout <<  !((1 || 0) && 0);  // 1 (Parenthesis are useful)
  cout <<  ( 1 == 1 || 1 != 2);  // 1 (Parenthesis are useful)

  cout << endl;
}

if .. else ..
#include <iostream.h> 
int main() {
  int age; 
  cout<<"Please input your age: "; //Asks for age
  cin>>age;    //The input is put in age
  if(age<100)  {
     cout<<"You are pretty young!"; 
  } else if(age==100)  {
     cout<<"You are old"; 
  } else if(age>100) {
    cout<<"You are really old"; 
  }
  return 0;
}

There exists a goto syntax:
 
goto part1;
    ...
part1:
   ....

for( ; ; )
#include <iostream.h> 
void main()  { 
  for(int x=0;x<100;x++)  {  cout<<x<<endl; } 
  return 0; 
}

while
#include <iostream.h>
main()  { 
 int x=0; 
 while(x<100)  {
    cout<<x<<endl; 
    x++; 
  } 
}

do..while
#include <iostream.h>
int main() {
  int x;
  x=0;
  do  {
    cout<<"Hello world!";
  }while(x!=0); 
  return 0;
}

break & continue
   - used to jump from loops (and nested loops);commands

switch
#include <iostream.h> 
#include <conio.h> 
int main() { 
  int input; 
  cout<<"1. Play game"; 
  cout<<"2. Load game"; 
  cout<<"3. Play multiplayer"; 
  cout<<"4. Exit"; 
  cin>>input; 
  switch (input) { 
   case 1: playgame();  break; 
   case 2: loadgame();  break; 
   case 3: playmultiplayer(); break;
   case 4:  return 0; 
  default:  cout<<"Error, bad input, quitting"; 
  }
  return 0;
}

functions  home - top of the page -

function
#include <iostream.h>

int mult(int x, int y);    // prototype

int main() {
  int x, y;
  cout<<"Please input two numbers to be multiplied: ";
  cin>>x>>y;
  cout<<"The product of your two numbers is "<<mult(x, y);
  return 0;
}

int mult(int x, int y) {
  return x*y;
}

Simple parameters are passed by value (as in C).
Arrays are passed by pointer (as in C).
For example, these 2 functions are identical:
#include <stdio.h>

void f1(int *ar)   {ar[0]=5; ar[1]=6;  printf("inside function\n  %d %d\n",ar[0],ar[1]);}
void f2(int ar[2]) {ar[0]=5; ar[1]=6;  printf("inside function\n  %d %d\n",ar[0],ar[1]);}

Strings are just char arrays - passed by pointer.
Structures - copied by value (shallow copy - both C and C++). So it works differently for structures than for arrays.
To avoid copying you can, of course, pass pointers to structures.

New in C++ - passing by reference (alias) using "&" notation in the declaration (as opposed to "*" for pointer). See the table below:

Three types of passing parameters into functions:
 
passing Object
(make shallow copy)
Passing Pointer
(explicitly)
Passing Reference
(aliasing)
Call f(X) f(&X) f(X)
argument f(person x) f(person * x) f(person & x)
passing Object Pointer Pointer
Axess to X
from f( ) body
none *x x

Example: passing a reference:
 
#include <iostream.h>
void f (int & x) { x = 2; }
void main() {
  int a=1;   cout << a << endl;
  f(a);       cout << a << endl;
}

Use the word "const" when passing an argument to tell the function that it can NOT change it.

You can pass pointers to functions as parameters:
 
// prototype two functions
void sort1(int* pArr, int n);
void sort2(int* pArr, int n);

// prototype the function to which we will pass 
// a pointer to one of the first two functions
void myfunc(int ii, char cc, void (*pSort)(int*, int));

// declare a pointer
void (*mysort)(int*,int);

int arr[100] = { ... }; // initialize the array
int nc=6;

// now we can work:
mysort = sort1;    myfunc(5,'A',(*mysort)(arr,nc));
mysort = sort2;    myfunc(5,'A',(*mysort)(arr,nc));

Example: passing an array of strings:

void showStrings(char* parr[], int Nelements);
    // here each element of array contains a pointer to a string (to a char array).

Note: passing array as a parameter does NOT copy the whole array,
but passes the address. Example:

#include <iostream>
using namespace std;

void myprint (int arr[], int len) {
  for (int ii=0; ii<len; ii++)
    cout << arr[ii] << " ";
  cout << "\n";
}

int main () {
 int myarr[] = {1,2,3,4,5};
 myprint(myarr,5);
  return 0;
}


Function prototype - shows return type, mame, and types of parameters. No function body. Just to inform the compiler - so that it can process calls to this function. The actual definition of the function can be placed somewhere futher down the file.
Example:
   double cube(double x);

Inline function: - if function is defined with inline keyword - the compiler may choose to replace the function calls with the actual code from the function. This makes the code run faster - but also increases the size of the code, so be careful. Synax is straightforward:
#include <iostream.h>
inline void hello(void) {
  cout<<"hello";
}
int main() {
  hello();
  return 0;
}

Default Arguments:
You can define default values for function parameters, for example:
 
void say(int N1=1, int N2=2);

void say(int N1, int N2) {
  cout << N1 << N2 << endl;
}

Function overloading - you may have several functions with the same name, but with different parameter lists.

Template function - generic function that can be used with different data-types. Big libraries of templates exist (example: STL - Standard Template Library).
 

working with strings  home - top of the page -

 
"This is a static string"
char string[50];  // make last element a '/0' character
char ss[] = "ABC";    // will have 4 elements - last will be '\0'
cout << sizeof ss;    // 4
char ss[] = {'A','B','C','\0'};   // same
char ss[] = "";    // contains single char '\0'
cout << "A\0BC" << 'D';  // AD , because \0 signifies the end of the string

//-------------------
char hello[] = "Hello, ";
char name[256] = '';
cout << "Enter your name: ";
cin >> name;
cout << hello << name << endl;
//-------------------
i=0; do  to[i] = from[i]; while (from[i++]);  // copying strings
or
while (*to++ = *from++); // copying strings
//-------------------
// array of strings = 2-dim array:
char names[5][20] = { "name1","name2","name3","name4","name5"};
//-------------------
//-------------------
char *arry;
arry = new char[256];
delete [] arry;  // to use delete you must put [] between delete and arry to tell it to free all 256 bytes of memory allocated.

Using cin>> to input a string works, but it will terminate the string after it reads the first space.
The best way to handle this situation is to use the function cin.getline. Technically cin is a class, and you are calling one of its member functions. The prototype for that function is:
cin.getline(char *buffer, int length, char terminal_char);

The char *buffer is a pointer to the first element of the character array, so that it can actually be used to access the array. The int length is simply how long the string to be input can be at its maximum (how big the array is). The char terminal_char means that the string will terminate if the user inputs whatever that character is. Keep in mind that it will discard whatever the terminal character is.

It is possible to make a function call of cin.getline(arry, '\n'); without the length, or vice versa, cin.getline(arry, 50); without the terminal character. Note that \n is the way of actually telling the compiler you mean a new line, i.e. someone hitting the enter key.

For a example:
#include <iostream.h>
int main() {
  char string[256];   //A nice long string
  cout<<"Please enter a long string: ";
  cin.getline(string, 256, '\n'); //The user input goes into string
  cout<<"Your long string was:"<<endl<<string;
  return 0;
}
Note:  you are actually passing the address of the array when you pass string because arrays do not require a reference operator (&) to be used to pass their address. Other than that, you could make \n any character you want (make sure to enclose it with single quotes to inform the compiler of its character status) to have the getline terminate on that character.

String.h is a header file that contains many functions for manipulating strings. One of these is the string comparison function.

int strcmp(const char *s1, const char *s2);  // compares 2 strings, returns negative, zero or positive result
int strcmpi(const char *s1, const char *s2);  // not case sensitive
char *strcat(char *desc, char *src);    // string concatenate
char *strupr(char *s);   // converts to uppercase
char *strlwr(char *s);   // converts to lowercase
size_t strlen(const char *s);  // the length of a string, minus the termating character(\0).
#include <iostream.h>   // For cout
#include <string.h>     // For many of the string functions
int main()  {
  char name[50];
  char lastname[50];
  cout<<"Please enter your name: ";
  cin.getline(name, 50, '\n');       //Use gets to input strings with spaces or 
                                               //just to get strings after the user presses enter
  if(!strcmpi("Alexander", name))   // strcmpi returns 0 for equal strings
    cout<<"That's my name too."<<endl; 
  } else { 
     cout<<"That's not my name."; 
  } 

   cout<<"What is your name in uppercase..."<<endl; 
  strupr(name);            //strupr converts the string to uppercase
  cout<<name<<endl; 

  cout<<"And, your name in lowercase..."<<endl;
  strlwr(name);                    //strlwr converts the string to lowercase
  cout<<name<<endl;

  cout<<"Your name is "<<strlen(name)<<" letters long"<<endl;  //strlen returns the length of the string

  cout<<"Enter your last name:";
  cin.getline(lastname, 50, '\n');
  strcat(name, " ");   // add space to the end
  strcat(name, lastname);    // add last name
  cout<<"Your full name is "<<name;
  return 0;
}

text files read/write  home - top of the page -

Reading/writing text files

C++ has two basic classes to handle files, ifstream (input) and ofstream (output). To use them, include the header file fstream.h.

Declaration:
ifstream a_file;
a_file.open()
a_file.close()
ifstream a_file("filename");   // declare and open the file for input in one command

Because C++ supports overloading operators, it is possible to use << and >> in front of the instance of the class as if it were cout or cin.
For example:
#include <fstream.h>
#include <iostream.h>

int main() {
  char str[10];

  // writing to a file
  ofstream a_file("example.txt");
  a_file<<"This text will now be inside of example.txt"; 
  a_file.close(); 

  // reading from a file
   ifstream b_file("example.txt"); 
  b_file>>str; 
  cout<<str; 
  b_file.close(); 
}

The default mode for opening a file with ofstream's constructor is to create it if it does not exist, or delete everything in it if something does exist in it. If necessary, you can give a second argument that specifies how the file should be handled.
For example:
  ofstream a_file("test.txt", ios::app);   // open for appending

Possible values:
    ios::app -- Opens the file, and allows additions at the end
    ios::ate -- Opens the file, but allows additions anywhere
    ios::trunc -- Deletes everything in the file
    ios::nocreate -- Does not open if the file must be created
    ios::noreplace -- Does not open if the file already exists

Example: reading text file
#include <stdlib.h>  // header needed for exit()
#include <fstream.h>

int main() {
  const int MAX = 80;
  char buf [MAX];

  ifstrearm input ("somefile.txt");
  if (! input) { cout << "Error opening file\n"; exit(-1); }
  while (input) { 
    input.getline(buf, MAX);
    cout << buf << endl;
  }
}

binary file read/write  home - top of the page -

Example: writing/reading a binary file
writing binary reading binary
#include <stdlib.h>  // header needed for exit()
#include <fstream.h>

int main() {
  ofstrearm output ("somefile", ios::binary);
  if (! output) { cout << "Error opening file\n"; exit(-1); }

  char text1[80] = "\n\tSome text\n";
  char text2[80] = "\tSome other text";
  char text3[80] = "\n\n\tAnd more\n";

  output.write((char *) &text1, sizeof(text1));
  output.write((char *) &text2, sizeof(text2));

  for (int i=0;i<sizeof(text3);i++) output.put(text3[i]);
  for ( i=32;i<256;i++) output.put((char) i);
  output.close();
}

#include <stdlib.h>  // header needed for exit()
#include <fstream.h>

int main() {
  ifstrearm input ("somefile", ios::binary);
  if (! input) { cout << "Error opening file\n"; exit(-1); }

  char text1[80], text2[80], text3[80];

  input.read((char *) &text1, sizeof(text1));
  input.read((char *) &text1, sizeof(text1));

  for (int i=0;i<sizeof(text3);i++) input.get(text3[i]);
  char ch;
  for ( i=32;i<256;i++) {
    if (i % 40 == 0) cout << endl;
    input.get(ch); cout << ch;
  }
  output.close();
}

File pointer:
#include <iomanip.h>
long FP = input.tellg(); // get file pointer
input.seekg(0,ios::beg); // set file pointer
input.seekg(-,ios::end); // set file pointer

seekg(), tellg() - set and get the value of a get pointer
seekp(), tellp() - set and get the value of a put pointer

Random Access to a File:
fstream myfile;
myfile.open("file_name", ios::app | ios::in | ios::out | ios::binary);

command line arguments  home - top of the page -

Accepting command line arguments
int main(int argc, char* argv[]) - // argc - int number of arg values +1 , because argv[0] is full path name of the program itself
 
#include <fstream.h> //Needed to manipulate files
#include <iostream.h>
#include <io.h>      //Used to check file existence
int main(int argc, char * argv[])
{
  if(argc!=2)
  {
    cout<<"Correct input is: filename"; 
    return 0; 
  } 
  if(access(argv[1], 00)) //access returns 0 if the file can be accessed 
  {     //under the specified method (00)
    cout<<"File does not exist";  //because it checks file existence
    return 0;
  }
  ifstream the_file;  //ifstream is used for file input
  the_file.open(argv[1]); //argv[1] is the second argument passed in 
    //presumably the file name 
  char x;
  the_file.get(x); 
  while(x!=EOF)  //EOF is defined as the end of the file
  {
    cout<<x;
    the_file.get(x);//Notice we always let the loop check x for the end of 
  }  //file to avoid bad output when it is reached
  the_file.close();  //Always clean up
  return 0;
This program first checks to ensure the user added the second argument (a file name). It checks this, using the access function, which accepts a file name and an access type, with 00 being a check for existence. This is not a standard C++ function (it may not work on all compilers). Then it creates an instance of the file input class, and it opens the second argument passed into main. get is a standard function used in input and output that is used to input a single character into the character passed to it, or by returning the character. EOF is simply the end of file marker, and x is checked to make sure that the next output is not bad.

Example - linked lists  home - top of the page -

Linked lists
consists of structures (nodes) pointing to the next node.
In memory it is often described as looking like this:
----------        ----------
- Data   -       >- Data   -
----------     -  ----------
- Pointer- - -    - Pointer-
----------        ----------
struct node {
  int x;
  node *next;
};

int main() {
  node *root;
  root=new node; 
  root->next=NULL; 
  root->x=5; 
  return 0; 

Here's what that looks like:
struct node {
  int x;
  node *next;
};

int main() {
  node *root;
  node *conductor; 
  root=new node;
  root->next=NULL; 
  root->x=12;
  conductor=root;
  if(conductor!=NULL) {
    while(conductor->next!=NULL) {
      conductor=conductor->next; 
    }
  }
  conductor->next=new node; //Creates a node at the end of the list
  conductor=conductor->next; //Points to that node
  conductor->next=NULL; //Prevents it from going any further
  conductor->x=42;
}

That is the basic code for traversing a list.
Example: ouputing the linked list:
conductor=root;
if(conductor!=NULL) {
  while(conductor->next!=NULL) {
    cout<<conductor->x;
    conductor=conductor->next;
  }
  cout<<conductor->x;
}
The final output is necessary because the while loop will not run once it reaches the last node, but it will still be necessary to output the contents of the next node. Consequently, the last output deals with this

recursion  home - top of the page -

Recursion
Recursion is defined as a function calling itself. Be careful. The computer keeps function calls on a stack and once too many are called without ending, the program will terminate. Try this:
#include <iostream.h>
void recurse(int count) {
  cout<<count; 
  recurse(count+1); 

int main() {
  recurse(1);   //First function call, so it starts at one
  return 0; 
}

functions with variable nubmer of arguments  home - top of the page -

Functions with variable-length argument lists
Some library functions can accept a variable list of arguments (such as the venerable printf). You can write your own (for example to calculate average of a variable number of numbers). You would use the stdarg.h header file. Place an ellipsis (which looks like '...') in place of the last argument. This will tell the compiler that the function should accept variable number of paramenters.
There are four parts needed:
 - va_list - datatype stores the list of arguments.
 - va_start - macro to initialize the list, accepts 2 arguments: a va_list and the name of the variable that directly precedes the ellipsis (...).
 - va_arg - returns the next argument in the list, accepts 2 args (a va_list and a variable type), and returns the next argument in the list in the form of whatever variable type it is told.
 - va_end - cleans up the variable argument list.

Example:
#include <stdarg.h>
#include <iostream.h>
double average(int num, ...) {
  va_list arguments;        // A place to store the list of arguments
  va_start(arguments, num); // Initializing arguments to store all values
  int sum=0;
  for(int x=0; x<num; x++)  sum+=va_arg(arguments, double);
  va_end(arguments);     //Cleans up the list
  return sum/(double)num;  //Returns some number (typecast prevents trunctation)
}

int main() {
  cout<<average(3, 12.2, 22.3, 4.5)<<endl;
  cout<<average(5, 3.3, 2.2, 1.1, 5.5, 3.3)<<endl;
  return 0;
}

splitting program into separate files  home - top of the page -

Splitting program into separate files: - put functions declarations in a header file - and include it where necessary.
Then you can compile them together:
c++   f1.cpp   f2.cpp   f3.cpp

myheader.h:
#include <iostream.h>

void f1();
void f2();
void f3();

f1.cpp:
#include <myheader.h>

void main() { cout << 1; f2(); }
void f1() { f3(); }

f2.cpp:
#include <myheader.h>
void f2() { f1(); }

f3.cpp:
#include <myheader.h>
void f3() { cout << 3; }

static int f();  // static means visible only in the current file.
extern void f(); // extern just says that the function is described elsewhere. It is not really needed.
 

input / output:
cin, cout, cerr
cin.unsetf(ios::skipws);  // not to skip whitespace
cin.eof() - special function to detect end of file
cin.bad() - checks success
char c = ' ';
while(1) {
  cin >> c;
  if (cin.eof()) break;
  if (cin.bad()) { cerr << "Input Error\n"; break; }
  cout << c;
  if (cout.bad()) { cerr << "Output Error\n"; break; }
}

 

misc  home - top of the page -

// --------------------------
(*p).Height = 55;
strcpy(p->Name,"somename");
// --------------------------
setw(20) - sets width of the next output
#include <iostream.h>
#include <iomanip.h>
cout << setw(20) << "something" << setw(12) << "something else"
// --------------------------
&a[i]    same as    &(a[i])
x[y]    same as   *(x+y)
x[4]   same as   4[x]
// --------------------------
Person *p = A+2;  // pointer initializing
(p-2) -> Name
&p[-2]->Name
p[-2].Name
(++p)->Name
// --------------------------
union {
  Person P[500];
  Mountain M[1000];
} U1;
// --------------------------

OOP - classes, constructors, destructor.  home - top of the page -

OOP = Object Oriented Programming.  Main idea - to make code modular and reusable. You keep methods close to the data they working on. You use inheritance to simplify development.  While inheriting, you can override methods (polymorphism).

C++  =   C    +    one big addition (objects)    +    bunch of small additions.
Classes = definitions (templates) of objects.
Class lists data structures (members) and functions (called methods).
Objects are instances of classes.
Varialbes in classes can be public, protected or private.
Classes should always contain two functions: a constructor (named as class) and a destructor (named   ~class_name).
NEITHER constructors NOR destructors RETURN AN ARGUMENT!
Example of a class definition:
#include <iostream.h>

class Computer {
  public:   //This restriction acts on all definitions under this, until a new type of restriction is placed
    Computer();   //Constructor
    ~Computer();  //Destructor
    void setspeed(int p);  // member function - will be defined outside
    int readspeed();         // member function - will be defined outside

  protected:
    int processorspeed;
};   // end of class definition - note a semicolon !!

Computer::Computer() { //Constructors can accept arguments, but this one does not
  processorspeed = 0;
}

Computer::~Computer() {  //Destructors do not accept arguments

void Computer::setspeed(int p) { 
   processorspeed = p;
}

int Computer::readspeed()  { 
  return processorspeed;
}

int main() {
  Computer compute;  // create an instance of a class (an object)
  compute.setspeed(100); 
  cout<<compute.readspeed();
  return 0;
}

Notes about constructors:
    A class may have multiple constructors.
    When you create an instance - the arguments of that instance determine selection of the appropriate constructor (if there are more than one constructor).
    Default constructor - a constructor with no parameters when all parameters have default values.
    If the class doesn't have a constructor, C++ creates a default one.
    Copy constructor - one of parameters has the type of the class
    Array of instances - requires the use of the default constructor

Destructor:
    A class may have only one destructor - the name is  ~className
    If you don't provide a destructor - C++ will create a default one for you
    Use destructor to free memory, close opened files, and do other cleaning tasks

Note:
  Same way you define class - you can also define a structure. There are two differences:
    = use the word "struct" instead of "class"
    = by default:
        the members of a structure are public,
        the members of a class are private.

Note:
The keyword "this" may be used in member functions. It is the pointer to an object which member function is called.

Note: if you have constructor(s) with just one argument - you can initialize the class like this:
class mountain {
   public:
   mountain(char *);
   //...
};

mountain E = "Everest";  // this will use the constructor with one parameter
 


 
 
 

friend, nested, static, namespace home - top of the page -

friend function - a regular function, having an instance of a class as one of its parameters.
friend function has access to all members of the class (even the private ones).
A function can be a friend of more than one class
A member functioin of one class can be a friend for another class
If you want to make all functions of one class to be friends of another class - just make the whole class a friend:
class mountain {
   friend class continent;  // continent is a friend of mountain
   // ...
};

class continent { .. };
 

Note:
  If class A is a friend of class B, this doesn't mean that class B is necessarily a friend of class A. But it can be.

Note:
  there may be a member function and external friend function with the same name. There is no confusion, because their fully qualified names (with namespace prepended) are different.
 

Nested Data Types:
  C++ allows to declare enumerated types, structures, and classes inside other classes. Their fully qualified name starts with the name of the external (host) class, for example:  Window::Rectangle.

static members (data and functions):
static - belongs to a class - not to an instance.
   static data - there is only one copy of this data, regardless of how many objects of this class are created. It may be used for counting class instances, shared information, iterators, shared error status, instance communication, etc.
Note: (important): The declaration of the static member in a class does NOT define it. You have to define/initialize a static member outside the class. For example:
class Account {
  public:
    // ...
  private:
    static int deposits;
};
 

// defining and initializing of the static variable. 
// Note, that this works even though deposits is a private variable
int Account::deposits = 0; 
 

  static member functions: - is used to access nonpublic static data members (which are usually made protected) and other static functions. It can not use the pointer "this", because it doesn't depend on a specific object.

namespace feature
You can define names for classes, variables, types in different namespaces.
If NN is the name of a namepsace, and cc - name of the variable defined in this namespace, then
  NN::cc
is a fully qualified name for this variable.
The default global namespace is an empty string, so you can write:
    ::cc   or  simply  cc
The standard library is defined in the namespace std

Operator overloading  home - top of the page -

Operators:
  You can declare operators in a class - essentially member functions that have special declaration and usage syntax.
  For example:
     operator+ ( )
     operator- ( )
     etc.

  Here is an example of declaration:
 
#include <iostream.h>

class number {
  public:
  int n;
  number( ) {n=1;}
};

number  operator+  (number N1, number N2) {
  number T;
  cout<<"\nAdding two numbers ";
  T.n = N1.n + N2.n;
  return T;
}

number  operator+  (int N1, number N2) {
  number T;
  cout<<"\nAdding integer to number ";
  T.n = N1 + N2.n;
  return T;
}

void main( ) {
  number X,Y,Z;

  Z = operator+(X,Y);  // explicit call to operator+( ) function
    cout<<Z.n;
  Z = X + Y;  // implicit call
    cout<<Z.n;

  Z = operator+(1,Y);  // explicit call to operator+( ) function
    cout<<Z.n;
  Z = 1 + Y;  // implicit call
    cout<<Z.n
;
  cout<<endl;
}

Output:
Adding two numbers 2
Adding two numbers 2
Adding integer to number 2
Adding integer to number 2
 

Using friend operator function (to access private nenbers):
 
#include <iostream.h>

class number {
  int n; //private
  public:
  number( ) { n=1;}
  friend number&  operator+  (number& , number&);
  friend ostream&  operator<<  (ostream& , number&);
};

number T; // temporary global object

number&  operator+  (number&  N1, number&  N2) {
  T.n = N1.n + N2.n;
  return T;
}

ostream&  operator<<  (ostream&  Cout, number&  N) {
  Cout << ' ' << N.n << ' ';
  return Cout;
}

void main ( ) {
  number  X, Y, Z = X + Y;
  cout << X << '+' << Y << '=' << Z;  // 1 + 1 = 2
}

abstract class, parent-child hierarchy home - top of the page -

abstract classes
class is abstract if it has at least one pure virtual function
(function is made "pure" by using initializer "=0"), for example:
class Shape {
   public:
       virtual void draw( ) = 0;  // pure virtual function
      // more definitions
}
An abstract class can be used only as a base for other classes - or as an interface (without exposing any implementation details).

class hierarchy (inheritance)
Here is how to declare a descendant class ( MyChildClass ) from a parent class ( MyParentClass ):
 
class MyChildClass : public MyParentClass {
    public:
        // constructors, destructor, members, member functions
    protected:
        // constructors, destructor, members, member functions
    private:
        // constructors, destructor, members, member functions
}

children inherit data and function members from parent(s)
 

multiple inheritance
it is possible to have several parents, for example:
 
class MyChildClass : MyParentClass1, MyParentClass2 {
  // ... 
}

The parents in the list may have prefixes like "virtual" or/and "public", for example:
 
Class MyObject {..}
class Salary : virtual public MyObject { ... }
class Person : virtual public MyObject { ... }
class Employee : virtual public Person, virtual public Salary { ....}

Note:
  "virtual" tells the compiler that parents share common ancestors
  "public" tells the compiler that class instances can access the public members (of the parent). Without this word, the inheritance will be by default private, so only the member functions of children can access the public members of the parent class.

private,protected, public (inheritance and encapsulation) home - top of the page -

access modifiers: public, protected, private
  - private is a default for members of a class
  - public is a default for members of a struct
  - the access level does not apply when defining the member outside of its class (this is used when defining the static members)

members:
public member:
     can be accessed from anywhere, including from outside the class

protected member:
  can be accessed within the class and within the derived classes
(compare with Java where protected means accessible from derived classes and to others in this package).

private member:
  can be accessed only within the class
 

classes:

class MyAccount: public Account;
 
public inheritance:
   This is an "is a" relationship between derived classes and the base class
   - public members in the base class remain public in the derived classes.
   - protected members in the base class remain protected in the derived classes

protected inheritance:
   This is an "implemented in terms of"  relationship between derived classes and the base class
   - public members in the base class become protected in the derived classes.
   - protected members in the base class remain protected in the derived classes

private inheritance:
   This is a stricter "implemented in terms of"  relationship between derived classes and the base class
   - public members in the base class become private in the derived classes.
   - protected members in the base class become private in the derived classes

virtual functions home - top of the page -

Imagine that we create a generic class (Parent) with functions which will be overriden in children. Imagine that we have an array of pointers of the Parent type, and we point these pointers to objects of different derived classes. Imagine that we want to call certain method on all these objects. And instead of simply calling the same generic method from the Parent, - we want the compiler to do some extra work and trace to call different overriding methods from child classes. So that the method should correspond to the object. To achieve that we should add the word "virtual" in front of the function declaration.

So the word "virtual function" means that the function declaration serves like an interface. It can be overriden (re-defined) in the derived classes. If the function is virtual, than the compiler and loader will call the correct function for an object.

- virtual function can override a virtual or nonvirtual member function that is inherited from a parent class
- "once virtual - always virtual" - a virtual parent in parent can not be overriden in children by a nonvirtual function.
- you may overload a virtual function with a nonvirtual function. However the children can inherit only the virtual function.

Here is an example showing the difference in virtual / non-virtual  behaviors:
 
#include <iostream.h>

class P {  // Parent
  public:
  void fun() { cout<<"p_fun"<<endl; }
  void virtual vfun() { cout<<"p_vfun"<<endl; }
};

class C : public P {   // Child class derived from Parent
  public:
  void fun() { cout<<"c_fun"<<endl; }                 // override in child
  void virtual vfun() { cout<<"c_vfun"<<endl; }   // override in child
};

main() {
  P *pp; // pointer of parent type
  C c, *pc;
  pc = &c; 
  pp = &c; 
     // pointer pp is of type "parent" - but points to a child class object
     // question - will it call the function of a child or of a parent?
     // see below - the answer is different for non-virtual or virtual functions

  //  non-virtual
  cout<<"fun():"<<endl;
  cout<<"child   : ";     c.fun();
  cout<<"child  p: "; pc->fun();   // (*pc).fun();
  cout<<"parent p: "; pp->fun();   // (*pp).fun();

  //  virtual
  cout<<"virtual vfun():"<<endl;
  cout<<"child   : ";     c.vfun();
  cout<<"child  p: "; pc->vfun();  // (*pc).vfun();
  cout<<"parent p: "; pp->vfun();  // (*pp).vfun();
  cout<<endl;
}

output:
fun():
child   : c_fun
child  p: c_fun
parent p: p_fun   // note here it calls the function of the parent
virtual vfun():
child   : c_vfun
child  p: c_vfun
parent p: c_vfun   // and here it calls the function of the child, because the function is virtual

Virtual function allow for polymorphism, one of the great buzz words in Object Oriented programming. What this means is that objects of different derived classes can respond to the exact same message in different ways. In the example above, a child class "C" is derived from a parent class "P". A pointer "pp" of the parent type is pointed to an object "c" of the child type. Now if this pointer is used to call a function which is defined in the parent and overriden in the child, then the question is: which function will be used:
   - the one defined in parent (as the pointer is of the parent type)
   - or the one defined in the child (because the object is of the child type).
Please note the diffference when this pointer is used to call a virtual or non-virtual functions. Note that for virtual function the method of the child is called. Which is probably what you want. Thus with a virtual function, the class of the object pointed to determines the function definition to be used.

Exceptions home - top of the page -

Exception classes:
   Skeleton classes - no members
   Classes with data members

Standard Exceptions:
 
Exception Class Parent Class Purpose
exception None The base class for all of the exceptions thrown by the C++ standard library
logic_error Exception Reports logical program errors that can detected before the program proceeds to execute subsequent statements
runtime_error Exception Reports runtime errors that are detected when the program executes certain statements
ios::failure Exception Reports stream I/O errors
domain_error logic_error Reports infraction of a condition
invalid_argument logic_error Signals that the argument of a function is not valid
length_error logic error Signals that an operation attempts to create an object with a length that exceeds or is equal to NPOS (the largest value of the type size size_t)
out_of_range logic_error Signals that an argument is out of range
bad_cast logic_error Report an invalid dynamic cast expression during runtime identification
bad_typeid logic_error Reports a null pointer in a type identifying expression
range_error runtime_error Signals invalid postcondition
overflow_error runtime_error Signals arithmetic overflow
bad_alloc runtime_error Signals the failure of dynamic allocation

Throwing an exception:
throw exceptionObject;

try {
  // throw myError
}
catch(int myError) {
  // process error here
}

templates  home - top of the page -

Often you need to have a class to do the same operation - but with different data types.  Then you can define a template one time - and then use it in the code with different types:

Example: let's create a template to hold 3 objects - and calculate their sum( ).
template <typename T>
class  coolHolder { 
  public: 
  T  i,j,k;
  T sum( ) { return i + j + k; }
};

Now here is how we can use this template with different types (int , float):
void main( ) {

  coolHolder<int> IntHolder;
  IntHolder.i=1; IntHolder.j=2; IntHolder.k=3;
  cout<<IntHolder.i<< endl;

  coolHolder<int> AnotherIntHolder;
  AnotherIntHolder.i=4; AnotherIntHolder.j=5; AnotherIntHolder.k=6;
  cout<<IntHolder.i<< endl;

  coolHolder<float> FloatHolder;
  FloatHolder.i=3.14; FloatHolder.j=4.14; FloatHolder.k=5.14;
  cout<<IntHolder.i<< endl;

}

The code of functions in template can be declared inside the template class declaration, but detailed later outside the class declaration, for example:
template <typename T>
class  myclass { 
  protected: T x;
  public: 
    T& getx( );  // function returns a reference. This allows to avoid unnecessary copying.
    void setx(T);
};

template <typename T>
T  &myclass<T>::getx( ) {  // this is a template for getx( )
  return x;
}

template <typename T>
void  &myclass<T>::setx(T newx) {  // this is a template for setx( )
  x= newx;
}
 

void main( )
  myclass<int>  ss;
  ss.setx(10);
  cout  <<  ss.getx( ) << endl;
}

Note: If you include a static member in a template - then each class that you create using this template will get its own static member. As usually with static data members, you have to define the storage (initialize the variable) outside of the class declaration. Example:
#include <iostream.h>
#include <stdlib.h>

// first, class declaration template
template <typename T>
class  myClass { 
  public: 
  static T mystatvar;
};

// second, static variable definition template
template <typename T>
T myClass<T>::mystatvar;

// now we can define and use it
void main( ) {
  myClass<int>::mystatvar=10;
  myClass<float>::mystatvar=3.14;
  myClass<int>  myInstance;
  myInstance.mystatvar=20;

  cout<< myClass<int>::mystatvar <<endl;
  cout<< myClass<float>::mystatvar <<endl;
  cout<< myInstance.mystatvar <<endl;
}

output:
20
3.14
20 

p.487:  parameterizing a template

...

programming with STL  home - top of the page -

p.508