Skip to content

Instantly share code, notes, and snippets.

@wutipong
Last active May 1, 2018 12:24
Show Gist options
  • Save wutipong/91588b2cf8ba07b7d7c40393e0186c2e to your computer and use it in GitHub Desktop.
Save wutipong/91588b2cf8ba07b7d7c40393e0186c2e to your computer and use it in GitHub Desktop.
C++ Training

C++ Training #1 - Basic Construct

Hello World

#include <iostream>
using std::cout;
using std::endl


int main(int argc, char** args) {
  cout<<"Hello World"<<endl;

  return 0;
}

The entry point of standard C++ program is main(). This is however depends on the platform of the application as well. In Windows' WIN32 has its entry point as WinMain() function.

Console output

To display console output, firstly import the header file iostream (using #include, which will be discussed later). And then use the stream operator to std::cout to put values into it. Stream can be chained so multiple value/variable can be chained at the same statement.

To end the line, put std::endl at the end.

cout<<"Hello" <<" World"<<endl;

preprocessor

Statement

Statements in C++ are ended by ;.

int a;
a = 100;
return;

Compound statements or blocks are grouped inside curly brackets {}.

{
  int a;
  a = 100;
}

Control Statement

if and else

if checks the condition and proceed with the following statement if the condition is true. else, if presents, perform its following statement when the if condition fails.

if(input % 2 == 0) std::cout << "Even Number" << std::endl;
else std::cout << "Odd Number" << std::endl;

switch/case

switch compare the input against all case value. If the input is found, it start performing at the statements the case label is placed at, until break is found.

The case label must contains constant numeric value. Thus it cannot be used with anything else rather than integer (enumerator can be used as well.). default is a special label which tagged at the statement it should start at when the input does not match any other label.

For example:

switch(input) {
  case 0:
    std::cout << "ZERO" << std::endl;
    break;
  case 1:
    std::cout << "ONE" << std::endl;
    break;
  case 7:
    std::cout << "SEVEN" << std::endl;
  default:
    std::cout << "HEAVEN" << std::endl;
    break;
}

From above example, if the input is 7, the output would be

SEVEN
HEAVEN

While other cases would print only one line. This phenomenal is called "fall-through".

while and do/while

while statements checks the condition and proceed with the following statement if the condition is true. After the statement is executed, the condition is rechecked again. This is repeated until the condition is false.

while(input < 0) input--;

do/while performs the statement following do keyword first, and then the condition is checked. If the condition is true then it re-perform the statement again. This is done repeatedly until the condition is false.

do input--;
while (input >= 0);

for

for contains 3 clauses. Initialization, Condition, and Increment. These three are put inside a pair of parenthesis, separated by semicolon.

for (<Initialization>; <condition>; <increment>) statement;

The initialization is only performed once before everything else begin. After that the condition is checked. If the condition is true then the statement is performed. Then the increment is performed. Finally the condition is re-checked again and if it's true the statement is performed one more time. This is performed repeatedly until the condition is false.

For example:

for(int i =0; i< SIZE; i++)
  std::cout<<i<<std::endl;

Variable

Variable in C++ can be declared as . For example int count, char delimeter, float average, string name.

Variables can be assigned its value by using assignment operator =.

int a;
a = 100;

Variables can be also declared and assigned at the same statement.

int a = 100;

If the data type can be deduced from the value the variable is being assigned, the data type can be replace by the keyword auto. This is useful in the context that the type is very complicated.

std::vector<int> vectorInt;
std::vector<int>::const_iterator iter1 = vectorInt.begin();
auto iter2 = vectorInt.begin();

Also auto provides the cleaner, less error-prone code. Consider :-

int a = 100l; //variable is int, the value is long.

and

auto a = 100l; //both are long.

Constants

Variables can be constant by using keyword const. Constant variable must be initialized right-away as the value cannot be updated afterward.

const int count = 100;

Data type

Data type can be either basic data type, pointer, reference (will be discussed later), or user define type e.g. struct, class, enum.

Boolean

bool can be either true or false, but nothing else.

bool tautology = true;

Integers

Integer types are char, wchar, int, short, long and long long. They can be either signed or unsigned. To specify whether or not it is signed or unsigned, put the keyword signed or unsigned, respectively, just before the integer data type name.

The size of these type are guarantee to be specific size, but is not necessarily exact to the number. For example short and long might be exactly the same size (e.g. 64-bit).

Integer literal may contains suffix to denote the type of the value. Eg. l for long, u for unsigned, ll for long long, ul for unsigned long, and ull for unsigned long long.

unsigned long long superLargeInt = 12345678901234567890ull;

char and wchar_t (wide character) are types used specifically for characters. char is strictly 8-bit character, while wchar_t is 16-bit or larger. Character literal is a single character inside single quote, with a prefix l for wide character.

char a = 'a';
wchar_t b = l'b';

Floating Points

Floating points are float and double. These are IEEE754 encoded floating points, with float being being single-precision (32-bit) and double being double-precision (64-bit).

Floating point literal requires decimal point . to be present in the value, or use the exponential form (not discussed here), otherwise it will be treated as integer. Floating point literals are by default double. To make it float use f prefix.

float a = 10.0f;
double b = 3.14;

Enumerators

Enumerators are data types which has predefined set of possible value. To define an enumerator use enum or enum class keyword.

enum DAY { DAY_MONDAY, DAY_TUESDAY, DAY_WEDNESDAY, DAY_THURSDAY, DAY_FRIDAY, DAY_SATURDAY};
enum class Month { January, February, March, April, May, June, July, August, September, October, November, December };

enum class was added in C++11. It is not available in any version before C++11 standard.

The value defined in enumerator are constant integer, it works almost the same way as a constant with an exception as it cannot be referred by reference operator (as it's not an variable). Value defined in enum are exposed globally, while the enum class contains the value within its name. For example

DAY day = DAY_MONDAY;
Month month = Month::April;

The value name defined in enum may clashes with other code, so it's advised to begin the name with the type name. Since enum class contains the value under its name already, this is already enforced.

Each value in an enumerator is an constant integer, the first value is 0, and the next one is larger then the other by 1. Each value can be assigned with a different value manually using assignment operator =. The value that is not specified explicitly will be larger then the one before by 1.

enum class Numeric {
  ONE = 1,
  TWO,
  THREE,
  FOUR,
  ZERO = 0
};

References

Reference is simply an alias to a variable. To define a reference, simply put & before the variable name. Reference required its value to be assigned immediately. The right-hand side of the assignment operator is needed to be a variable.

For example.

int avar = 100;
int &alias = avar; //alias is now an alias of avar

avar and alias are practically the same variable. Any assignment operation made to alias will change the value of avar as well.

alias += 100; //avar is now 200

A reference is expected to be the same type as the variable it refers to. Below code is illegal

int avar = 100;
float &alias = avar; // Illegal.

Reference can be auto as well.

int avar;
auto &alias = avar; //alias is int&

Pointers

Pointers are the type whose store a reference. To define a reference, put * before the variable name.

int *ptr;

The term referece here usually means a memory address where a data is stored. This can be a value returned by reference operator &, as well as a value returned by new operator.

int var = 100;
int *ptrToAvar = &avar;
int *ptrToSomeValue = new int(200); //new will be discuss later.

Pointer can also points to another pointer as well. Put more * in front of the variable name to do so.

int var = 100;
int *ptrToVar = &var;
int **ptrToPtrToVar = &ptrToVar;
int ***ptrToPtrToPtrToVar = &ptrToPtrToVar;

Pointers and const-ness

Pointers that points to constant variable needs a const keyword like below:

const int a = 100;
const int* ptr = &a; //(*ptr) cannot be reassigned, like a.
                     //However ptr can be reassigned to point to some other const int.

And pointers can be constant as well (which mean the cannot be reassigned), by putting the keyword after the asterisk.

int a = 100;
int* const ptr = &a; //any assignment to ptr after this is illegal, however (*ptr) is reassignable.

And finally constant pointer to constant variable.

const int a = 100;
const int* const ptr = &a; // both ptr and (*ptr) is not reassignable.

NULL and nullptr

NULL and nullptr are a special reference value which basically means nothing. They are used for placeholder for pointer which do not point to anywhere just yet.

int *ptr = nullptr;
int *ptrA = NULL;

Dereference operator *

Operation made to pointers updates the reference value it holds, not the value of the data referred by the reference (operator will be discuss later). For example.

int avar = 100;
int *ptrToAvar = &avar;
ptrToAvar += 1; //avar remains 100, ptrToAvar now points to something else.

To update the value of the data the pointer points to, use dereference operator *.

int var = 100;
int *ptrToVar = &var;
*ptrToVar += 1; //var is now 101.

Pointer arithmetics

Addition and subtraction, as well as increment and decrement operation, can be done to pointers. Adding 1 into a pointer results in the next value of the same time of the value it used to pointed to. For example :

// Array will be discussed in the next section.
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *p = &array[0];//p points to array[0]
std::cout<<*p<<std::endl; // 0
std::cout<<*(p+1)<<std::endl; // 1
std::cout<<*(p+5)<<std::endl; // 5

p += 4; // p is now pointed to array[4]
std::cout<<*p<<std::endl; //4
std::cout<<*(p-2)<<std::endl; // 2

p -= 1 //p is now pointed to array[3]

Arrays

Arrays are a group of data with the same type, sitting next to each other. To declare an array, use [] after the variable name.

int intArray[200];
char charArray[5000];

The number of element of data it holds is finite, and must be known to the compiler at compile time. The following code is invalid.

int count = 200;
int intArray[count]; //compile error.

Also the number of element cannot be dynamically obtained in code. So in the case that the size must be known, #define a macro and use it as the size constant.

#define BUFFER_SIZE 500
int buffer[BUFFER_SIZE];

In C++11 the const_expr can be used in this context, but Visual C++ 2012 does not support the keyword.

Arrays can be initialized with a list of value, using {} with a list of comma-seperated value. In this case the size can be omitted.

int intArray[] = {0, 1, 2, 3, 4, 5};
char charArray[] = {'h', 'e', 'l', 'l', 'o'};

To access to an element inside an array, put an index number inside []. Eg.

std::cout << intArray[50];
intArray[20] = 50;

The index number of an array can be any number from [0:n), which means 0<i<n, where n is the number of element the array is holding. Accessing an array using index which falls outside of this interval results in undefined behavior (mostlikely SEGFAULT).

Strings

In C++, a string literal is an character array ended with '\0' or NULL. The NULL character is added automatically by the compiler. String literal is a sequence of characters inside a pair of double quote "". This is the construct inherit from C. It can be assigned to a character array, like :-

char str[] = "Hello World"; // This array has 12 elements, with the last one is '\0'.

This is commonly called C-String.

A string literal can be assigned to a character pointer as well. This is not recommended and might results in warning with modern C++ compilers. However this form is even more common than the array form.

char *str = "Hello World"; //same as char str[].

Dynamically memory allocation using new and delete

new operator can be used to dynamically allocate memory inside heap/free store area. This operator returns a reference which must be assigned to a pointer.

new operator can be used to allocate a single instance of a data type, or an adjacent area with a number of instance of the same data type. For example.

int *pInt = new int;
int *pIntArray = new int[50];

The latter is called dynamic array. Dynamic array are created and allocated at the runtime. The size can be vary and is not required to be known to the compiler at compile time (as opposed to the static array).

int count = 200;
// int intArray[count]; results in  compile error. Instead use this.
int *intArray = new int[count];

Dynamic array works the similar way to static array and works with the same syntax.

After finishing using the memory allocated by new, these instances have to be deallocated manually using delete or delete[] operator, depends on whether it is single instance or a dynamic array. Failing to do so results in memory leak.

int *pInt = new int;
int *pIntArray = new int[50];
// ... snipped

delete pInt;
delete[] pIntArray;

Using delete on dynamic array results in memory leak (as only the first element is freed). Using delete[] on single instance results in undefined behavior (mostlikely SEGFAULT).

Scope and lifetime

Variables have their own lifetime, based on the scope it is declared. When an variable is declared outside any blocks, it's a global variable which lives in the global scope. If a variable is declared inside a block, it's a local variable.

Variable declared in a global scope will be created before the program begins (eg. main() is executed). Variable declared in a local scope will be created when the program runs into the line it is declared.

Keep in mind that

  1. Variable has to be declared before it can be used. The code that refers to this variable must be in the same or inner scope, must be written under the variable is declared.
  2. No variables with the same can be in the same scope. They can be however declared in different scope level, in this case the code that refers to the name refers to the variable closest to the scope the code lives.

For example:

std::cout << a << std::endl; //error, a is not declared at this point.
int a = 10;
int main(int argc, char** argv) {
  std::cout<< a <<std::endl; // error, a is not declared at this point.

  return 0;
}

int a = 10;

When the enclosing scope ends, the variable is destroyed and becomes invalid. The name cannot be referred in the code anymore.

It's possible to have a pointer points to this destroyed variable. If the value is accessed through this pointer, it results in undefined behavior (mostlikely SEGFAULT). This phenomenal is called dangling pointer

For example:

int *a;
if (input > 0) {
  int b = 20;
  a = &b;
}

std::cout << a << endl; //The program would crash here.

Functions

Functions are a set of command grouped into a single procedure. To define a function, use the syntax :

<returntype> <function name> (<parameter list>) {
  <body>
}

For example :

int max(int a, int b) {
  return a > b ? a: b;
}

return keyword is used to return the following value back to the function caller.

For function that does not return anything, use return type void.

void print(char str[]) { cout<<std::str<<endl;}

A function has to be declared before it can be use. The code above the function definition cannot refers to the function. For example, below code does not compile.

int main(int argc, char** argv){
  std::cout<< max(5, 10);
}

int max(int a, int b) {
  return a > b ? a: b;
}

Forward Declaration

Function can be forward declared, by placing the function's signature somewhere in the code. For example.

int max(int a, int b);

int main(int argc, char** argv){
  std::cout<< max(5, 10);
}

int max(int a, int b) {
  return a > b ? a: b;
}

A function can also be used in another file, given that it is forward declared.

// max.cpp
int max(int a, int b) {
  return a > b ? a: b;
}
// main.cpp
int max(int a, int b);

int main(int argc, char** argv){
  std::cout<< max(5, 10);
}

The forward declaration can be even placed into a separated file, called header files, and then use #include directive to include the function declaration into the file. #include directive basically take a content of a file and replace it self by that content.

// max.h A header file containing max()

#ifndef MAX_H
#define MAX_H

int max(int a, int b);
#endif
#include "max.h"
//main.cpp A file that use max()
int main(int argc, char** argv){
  std::cout<< max(5, 10);
}
#include "max.h"

//max.cpp A file that define max()
int max(int a, int b) {
  return a > b ? a: b;
}

Overloads

Function overloads are functions with the same name but different parameter list and/or return type

// max.cpp
int max(int a, int b) {
  return a > b ? a: b;
}

double max(double a, double b) {
  return a > b ? a: b;
}

Exception Handling

Exception is a way to handling errors. In c++, the exception value can be any type. For example:

if(value == nullptr) throw 0;

To catch the exception, use try/catch keyword.

#include <iostream>

int test(char a[]) {
  throw 0;
}

int main(int argc, char** argv) {
  try{
    test("abcdefg");
  } catch (int errorCode) {
     std::cout<<"Error Code : " << errorCode << std::endl;
  }

  return 0;
}

catch clause can be chained when the expected code might throw multiple type of value.

  try{
    test("abcdefg");
  } catch (int errorCode) {
    std::cout<<"Error Code : " << errorCode << std::endl;
  } catch (std::string errorText) {
    std::cout<<"Error : " << errorText << std::endl;
  }

use catch(...) to handle the case the type of exception might be unknown.

  try {
    test("abcdefg");
  } catch (int errorCode) {
    std::cout<<"Error Code : " << errorCode << std::endl;
  } catch (std::string errorText) {
    std::cout<<"Error : " << errorText << std::endl;
  } catch (...) {
    std::cout<<"Unknown error"<< std::endl;
  }

class and Object-Oriented Programming in C++

Object Oriented Concept Recap

OOC are programming paradigm which the program are represented by relationships between 'objects'. In OO-world, everything is object.

Class

Objects are classified into classes, which describes the properties of the object that belongs to itself. Properties in OO are attributes (data fields, data members, or properties), and operations (methods, member functions, or subroutine).

4 Main Concepts of OOP

Also called '4 pillars of OOP'.

Abstraction

Abstraction is to model part of the functionality into entities that is easily identifiable by the reader. In OOP, it is basically to group related functionalities into classes.

Encapsulation

Encapsulation is an ability to limit access to properties to certain groups of related entity. Most programming languages including C++ provides 3 levels of access.

  • public - The property can be access from any classes.
  • protected - The property can be access only by the owner and its derived classes.
  • private - The property can be access only by the owner.

Inheritance

Inheritance is the relationships between two class. The inheriting classes (derived classes, sub classes, or child classes) have the same properties as the inherited classes (super class, or parent classes).

Polymorphism

Polymorphism is the ability to display different behavior in the same operation by objects that belongs to the same classes.

For example, objects within the class Student are able to TakeNote(), but they might do so differently. Some of them might type, some might write, etc.

Object Oriented in C++

Class

In C++ class is one way to define user-define data types which is a composite of different data types. To define class, use the keyword class follows by name and a pair of curly brackets containing properties of the class.

class <className> { <classproperties> };

The class properties can be variable or functions. This is defined by a very similar syntax to its usual declaration. For example:

class AClass {
  int intProperties;
  void someFunction(int parameter) {
    print(parameter);
  }
};

Notice that the class definition ends with ;.

The function member definition can be moved out of the class, like:

class AClass {
  int intProperties;
  void someFunction(int parameter);
};

void AClass::someFunction(int parameter) {
  print(parameter);
}

And finally, the class definition can be put into a separated header file, just like functions' forward declaration.

aclass.h

#ifndef ACLASS_H
#define ACLASS_H
class AClass {
  int intProperties;
  void someFunction(int parameter);
};

#endif

aclass.cpp

#include "aclass.h"

void AClass::someFunction(int parameter) {
  print(parameter);
}

Object Creation

To create an object from a class, declare a variable as usual.

WebService service;

When the variable is declared, it is initialized right away without any needs to assign anything to it. However if the class accepts parameters during the object initialization, the parameters have to be supplied by a list of value insides a pair of parenthesis.

WebService staticHttp(80);

Objects can be dynamically created by using new operator as well.

WebService *staticHttp = new WebService(80);

Like other dynamically allocated data, it must be deallocated explicitly using delete keyword.

delete staticHttp;

Accessing object's properties.

To access a property inside object, use . operator. This can be done with both member variable and member functions.

std::cout << staticHttp.portNum << ": " <<staticHttp.GetName();

Also to access a property of an object via pointer, use -> operator.

WebService staticHttp(80);
WebService *ptr = &staticHttp;

std::cout << ptr->portNum << ": " <<ptr->GetName();

Also remember that accessing an un-allowed property results in compilation error. The access level will be discussed next.

Access level

As mentioned, class is able to limit the access to its members. In C++, the label syntax is used to declared that the properties under the label is either public, protected, or private.

class AClass {
private:
  int intProperties;
public:
  void someFunction(int parameter);
protected:
  void reservedOperation();
};

By default properties are private, however we should not relies on the default behavior as it can be confusing.

Constructor

Constructor is a function-like construct that is called during object's creation. Its main purpose is to initialize the object's member variable.

Constructor can be declared in a very similar way to function with exception of the return type. The constructor's name will be the same as the class name.

class AClass {
public:
  AClass(); //default constructor
  AClass(const AClass&); //copy constructor
  AClass(int a); // constructor
};

There are two specialized kind of constructor in C++, default contructor and copy constructor. If any of them is not explicitly defined, the compiler will add the missing one automatically. These two will be discussed later.

At constructor's definition, the value of its member variable can be initialized either assignment in the constructor body, or using constructor form after : sign just before the constructor body. The constant member can be also assigned this way as well. Any unassigned value will be left at its default value.

class WebService {
public:
  WebService(int _port);

private:
  const int port;
  std::vector<Client> client;
  std::string hostname;
};

WebService::WebService(int _port): port(_port), hostname(GetHostName())

Default Constructor

Default constructor is the constructor that does not takes any parameter.

# C++ Training #1 - Basic Construct
## Hello World
```c++
#include <iostream>
using std::cout;
using std::endl
int main(int argc, char** args) {
cout<<"Hello World"<<endl;
return 0;
}
```
The entry point of standard C++ program is `main()`. This is however depends on the platform of the application as well. In Windows' WIN32 has its entry point as `WinMain()` function.
## Console output
To display console output, firstly import the header file `iostream` (using `#include`, which will be discussed later). And then use the stream operator to `std::cout` to put values into it. Stream can be chained so multiple value/variable can be chained at the same statement.
To end the line, put `std::endl` at the end.
```c++
cout<<"Hello" <<" World"<<endl;
```
## preprocessor
## Statement
Statements in C++ are ended by `;`.
```c++
int a;
a = 100;
return;
```
Compound statements or _blocks_ are grouped inside curly brackets `{}`.
```c++
{
int a;
a = 100;
}
```
### Control Statement
#### `if` and `else`
`if` checks the condition and proceed with the following statement if the condition is true. `else`, if presents, perform its following statement when the `if` condition fails.
```c++
if(input % 2 == 0) std::cout << "Even Number" << std::endl;
else std::cout << "Odd Number" << std::endl;
```
#### `switch`/`case`
`switch` compare the input against all `case` value. If the input is found, it start performing at the statements the `case` label is placed at, until `break` is found.
The `case` label must contains constant numeric value. Thus it cannot be used with anything else rather than integer (enumerator can be used as well.). `default` is a special label which tagged at the statement it should start at when the input does not match any other label.
For example:
```c++
switch(input) {
case 0:
std::cout << "ZERO" << std::endl;
break;
case 1:
std::cout << "ONE" << std::endl;
break;
case 7:
std::cout << "SEVEN" << std::endl;
default:
std::cout << "HEAVEN" << std::endl;
break;
}
```
From above example, if the input is 7, the output would be
```
SEVEN
HEAVEN
```
While other cases would print only one line. This phenomenal is called "fall-through".
#### `while` and `do`/`while`
`while` statements checks the condition and proceed with the following statement if the condition is true. After the statement is executed, the condition is rechecked again. This is repeated until the condition is false.
```c++
while(input < 0) input--;
```
`do`/`while` performs the statement following `do` keyword first, and then the condition is checked. If the condition is true then it re-perform the statement again. This is done repeatedly until the condition is false.
```c++
do input--;
while (input >= 0);
```
#### `for`
`for` contains 3 clauses. Initialization, Condition, and Increment. These three are put inside a pair of parenthesis, separated by semicolon.
```c++
for (<Initialization>; <condition>; <increment>) statement;
```
The initialization is only performed once before everything else begin. After that the condition is checked. If the condition is true then the statement is performed. Then the increment is performed. Finally the condition is re-checked again and if it's true the statement is performed one more time. This is performed repeatedly until the condition is false.
For example:
```c++
for(int i =0; i< SIZE; i++)
std::cout<<i<<std::endl;
```
## Variable
Variable in C++ can be declared as <datatype> <varname>. For example `int count`, `char delimeter`, `float average`, `string name`.
Variables can be assigned its value by using _assignment operator_ `=`.
```c++
int a;
a = 100;
```
Variables can be also declared and assigned at the same statement.
```c++
int a = 100;
```
If the data type can be deduced from the value the variable is being assigned, the data type can be replace by the keyword `auto`. This is useful in the context that the type is very complicated.
```c++
std::vector<int> vectorInt;
std::vector<int>::const_iterator iter1 = vectorInt.begin();
auto iter2 = vectorInt.begin();
```
Also `auto` provides the cleaner, less error-prone code. Consider :-
```c++
int a = 100l; //variable is int, the value is long.
```
and
```c++
auto a = 100l; //both are long.
```
### Constants
Variables can be constant by using keyword `const`. Constant variable must be initialized right-away as the value cannot be updated afterward.
```c++
const int count = 100;
```
### Data type
Data type can be either basic data type, pointer, reference (will be discussed later), or user define type e.g. `struct`, `class`, `enum`.
#### Boolean
`bool` can be either `true` or `false`, but nothing else.
```c++
bool tautology = true;
```
#### Integers
Integer types are `char`, `wchar`, `int`, `short`, `long` and `long long`. They can be either signed or unsigned. To specify whether or not it is signed or unsigned, put the keyword `signed` or `unsigned`, respectively, just before the integer data type name.
The size of these type are guarantee to be specific size, but is not necessarily exact to the number. For example `short` and `long` might be exactly the same size (e.g. 64-bit).
Integer literal may contains suffix to denote the type of the value. Eg. `l` for `long`, `u` for `unsigned`, `ll` for `long long`, `ul` for `unsigned long`, and `ull` for `unsigned long long`.
```c++
unsigned long long superLargeInt = 12345678901234567890ull;
```
`char` and `wchar_t` (wide character) are types used specifically for characters. `char` is strictly 8-bit character, while `wchar_t` is 16-bit or larger. Character literal is a single character inside single quote, with a prefix `l` for wide character.
```c++
char a = 'a';
wchar_t b = l'b';
```
#### Floating Points
Floating points are `float` and `double`. These are IEEE754 encoded floating points, with `float` being being single-precision (32-bit) and `double` being double-precision (64-bit).
Floating point literal requires decimal point `.` to be present in the value, or use the exponential form (not discussed here), otherwise it will be treated as integer. Floating point literals are by default `double`. To make it `float` use `f` prefix.
```c++
float a = 10.0f;
double b = 3.14;
```
### Enumerators
Enumerators are data types which has predefined set of possible value. To define an enumerator use `enum` or `enum class` keyword.
```c++
enum DAY { DAY_MONDAY, DAY_TUESDAY, DAY_WEDNESDAY, DAY_THURSDAY, DAY_FRIDAY, DAY_SATURDAY};
enum class Month { January, February, March, April, May, June, July, August, September, October, November, December };
```
`enum class` was added in C++11. It is not available in any version before C++11 standard.
The value defined in enumerator are constant integer, it works almost the same way as a constant with an exception as it cannot be referred by reference operator (as it's not an variable). Value defined in `enum` are exposed globally, while the `enum class` contains the value within its name. For example
```c++
DAY day = DAY_MONDAY;
Month month = Month::April;
```
The value name defined in `enum` may clashes with other code, so it's advised to begin the name with the type name. Since `enum class` contains the value under its name already, this is already enforced.
Each value in an enumerator is an constant integer, the first value is 0, and the next one is larger then the other by 1. Each value can be assigned with a different value manually using assignment operator `=`. The value that is not specified explicitly will be larger then the one before by 1.
```c++
enum class Numeric {
ONE = 1,
TWO,
THREE,
FOUR,
ZERO = 0
};
```
### References
Reference is simply an alias to a variable. To define a reference, simply put `&` before the variable name. Reference required its value to be assigned immediately. The right-hand side of the assignment operator is needed to be a variable.
For example.
```c++
int avar = 100;
int &alias = avar; //alias is now an alias of avar
```
`avar` and `alias` are practically the same variable. Any assignment operation made to `alias` will change the value of `avar` as well.
```c++
alias += 100; //avar is now 200
```
A reference is expected to be the same type as the variable it refers to. Below code is illegal
```c++
int avar = 100;
float &alias = avar; // Illegal.
```
Reference can be `auto` as well.
```c++
int avar;
auto &alias = avar; //alias is int&
```
### Pointers
Pointers are the type whose store a reference. To define a reference, put `*` before the variable name.
```c++
int *ptr;
```
The term **referece** here usually means a memory address where a data is stored. This can be a value returned by reference operator `&`, as well as a value returned by `new` operator.
```c++
int var = 100;
int *ptrToAvar = &avar;
int *ptrToSomeValue = new int(200); //new will be discuss later.
```
Pointer can also points to another pointer as well. Put more `*` in front of the variable name to do so.
```c++
int var = 100;
int *ptrToVar = &var;
int **ptrToPtrToVar = &ptrToVar;
int ***ptrToPtrToPtrToVar = &ptrToPtrToVar;
```
#### Pointers and `const`-ness
Pointers that points to constant variable needs a `const` keyword like below:
```c++
const int a = 100;
const int* ptr = &a; //(*ptr) cannot be reassigned, like a.
//However ptr can be reassigned to point to some other const int.
```
And pointers can be constant as well (which mean the cannot be reassigned), by putting the keyword after the asterisk.
```c++
int a = 100;
int* const ptr = &a; //any assignment to ptr after this is illegal, however (*ptr) is reassignable.
```
And finally constant pointer to constant variable.
```c++
const int a = 100;
const int* const ptr = &a; // both ptr and (*ptr) is not reassignable.
```
#### `NULL` and `nullptr`
`NULL` and `nullptr` are a special reference value which basically means nothing. They are used for placeholder for pointer which do not point to anywhere just yet.
```c++
int *ptr = nullptr;
int *ptrA = NULL;
```
#### Dereference operator `*`
Operation made to pointers updates the reference value it holds, not the value of the data referred by the reference (operator will be discuss later). For example.
```c++
int avar = 100;
int *ptrToAvar = &avar;
ptrToAvar += 1; //avar remains 100, ptrToAvar now points to something else.
```
To update the value of the data the pointer points to, use dereference operator `*`.
```c++
int var = 100;
int *ptrToVar = &var;
*ptrToVar += 1; //var is now 101.
```
#### Pointer arithmetics
Addition and subtraction, as well as increment and decrement operation, can be done to pointers. Adding 1 into a pointer results in the next value of the same time of the value it used to pointed to. For example :
```c++
// Array will be discussed in the next section.
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *p = &array[0];//p points to array[0]
std::cout<<*p<<std::endl; // 0
std::cout<<*(p+1)<<std::endl; // 1
std::cout<<*(p+5)<<std::endl; // 5
p += 4; // p is now pointed to array[4]
std::cout<<*p<<std::endl; //4
std::cout<<*(p-2)<<std::endl; // 2
p -= 1 //p is now pointed to array[3]
```
### Arrays
Arrays are a group of data with the same type, sitting next to each other. To declare an array, use `[]` after the variable name.
```c++
int intArray[200];
char charArray[5000];
```
The number of element of data it holds is finite, and must be known to the compiler at compile time. The following code is invalid.
```c++
int count = 200;
int intArray[count]; //compile error.
```
Also the number of element cannot be dynamically obtained in code. So in the case that the size must be known, `#define` a macro and use it as the size constant.
```c++
#define BUFFER_SIZE 500
int buffer[BUFFER_SIZE];
```
In C++11 the `const_expr` can be used in this context, but Visual C++ 2012 does not support the keyword.
Arrays can be initialized with a list of value, using `{}` with a list of comma-seperated value. In this case the size can be omitted.
```c++
int intArray[] = {0, 1, 2, 3, 4, 5};
char charArray[] = {'h', 'e', 'l', 'l', 'o'};
```
To access to an element inside an array, put an index number inside `[]`. Eg.
```c++
std::cout << intArray[50];
intArray[20] = 50;
```
The index number of an array can be any number from [0:n), which means 0<i<n, where n is the number of element the array is holding. Accessing an array using index which falls outside of this interval results in undefined behavior (mostlikely SEGFAULT).
#### Strings
In C++, a string literal is an character array ended with `'\0'` or NULL. The NULL character is added automatically by the compiler. String literal is a sequence of characters inside a pair of double quote `""`. This is the construct inherit from C. It can be assigned to a character array, like :-
```c++
char str[] = "Hello World"; // This array has 12 elements, with the last one is '\0'.
```
This is commonly called C-String.
A string literal can be assigned to a character pointer as well. This is not recommended and might results in warning with modern C++ compilers. However this form is even more common than the array form.
```c++
char *str = "Hello World"; //same as char str[].
```
### Dynamically memory allocation using `new` and `delete`
`new` operator can be used to dynamically allocate memory inside heap/free store area. This operator returns a reference which must be assigned to a pointer.
`new` operator can be used to allocate a single instance of a data type, or an adjacent area with a number of instance of the same data type. For example.
```c++
int *pInt = new int;
int *pIntArray = new int[50];
```
The latter is called **dynamic array**. Dynamic array are created and allocated at the runtime. The size can be vary and is not required to be known to the compiler at compile time (as opposed to the static array).
```c++
int count = 200;
// int intArray[count]; results in compile error. Instead use this.
int *intArray = new int[count];
```
Dynamic array works the similar way to static array and works with the same syntax.
After finishing using the memory allocated by `new`, these instances have to be deallocated manually using `delete` or `delete[]` operator, depends on whether it is single instance or a dynamic array. Failing to do so results in memory leak.
```c++
int *pInt = new int;
int *pIntArray = new int[50];
// ... snipped
delete pInt;
delete[] pIntArray;
```
Using `delete` on dynamic array results in memory leak (as only the first element is freed). Using `delete[]` on single instance results in undefined behavior (mostlikely SEGFAULT).
### Scope and lifetime
Variables have their own lifetime, based on the *scope* it is declared. When an variable is declared outside any blocks, it's a **global variable** which lives in the **global scope**. If a variable is declared inside a block, it's a **local variable**.
Variable declared in a global scope will be created before the program begins (eg. `main()` is executed). Variable declared in a local scope will be created when the program runs into the line it is declared.
Keep in mind that
1. Variable has to be declared before it can be used. The code that refers to this variable must be in the same or inner scope, must be written under the variable is declared.
2. No variables with the same can be in the same scope. They can be however declared in different scope level, in this case the code that refers to the name refers to the variable closest to the scope the code lives.
For example:
```c++
std::cout << a << std::endl; //error, a is not declared at this point.
int a = 10;
```
```c++
int main(int argc, char** argv) {
std::cout<< a <<std::endl; // error, a is not declared at this point.
return 0;
}
int a = 10;
```
When the enclosing scope ends, the variable is destroyed and becomes invalid. The name cannot be referred in the code anymore.
It's possible to have a pointer points to this destroyed variable. If the value is accessed through this pointer, it results in undefined behavior (mostlikely SEGFAULT). This phenomenal is called *dangling pointer*
For example:
```c++
int *a;
if (input > 0) {
int b = 20;
a = &b;
}
std::cout << a << endl; //The program would crash here.
```
## Functions
Functions are a set of command grouped into a single procedure. To define a function, use the syntax :
```
<returntype> <function name> (<parameter list>) {
<body>
}
```
For example :
```c++
int max(int a, int b) {
return a > b ? a: b;
}
```
`return` keyword is used to return the following value back to the function caller.
For function that does not return anything, use return type `void`.
```c++
void print(char str[]) { cout<<std::str<<endl;}
```
A function has to be declared before it can be use. The code above the function definition cannot refers to the function. For example, below code does not compile.
```c++
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
int max(int a, int b) {
return a > b ? a: b;
}
```
### Forward Declaration
Function can be forward declared, by placing the function's signature somewhere in the code. For example.
```c++
int max(int a, int b);
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
int max(int a, int b) {
return a > b ? a: b;
}
```
A function can also be used in another file, given that it is forward declared.
```c++
// max.cpp
int max(int a, int b) {
return a > b ? a: b;
}
```
```c++
// main.cpp
int max(int a, int b);
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
```
The forward declaration can be even placed into a separated file, called *header files*, and then use `#include` directive to include the function declaration into the file. `#include` directive basically take a content of a file and replace it self by that content.
```c++
// max.h A header file containing max()
#ifndef MAX_H
#define MAX_H
int max(int a, int b);
#endif
```
```c++
#include "max.h"
//main.cpp A file that use max()
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
```
```c++
#include "max.h"
//max.cpp A file that define max()
int max(int a, int b) {
return a > b ? a: b;
}
```
### Overloads
Function overloads are functions with the same name but different parameter list and/or return type
```c++
// max.cpp
int max(int a, int b) {
return a > b ? a: b;
}
double max(double a, double b) {
return a > b ? a: b;
}
```
## Exception Handling
**Exception** is a way to handling errors. In c++, the exception value can be any type. For example:
```c++
if(value == nullptr) throw 0;
```
To catch the exception, use `try`/`catch` keyword.
```c++
#include <iostream>
int test(char a[]) {
throw 0;
}
int main(int argc, char** argv) {
try{
test("abcdefg");
} catch (int errorCode) {
std::cout<<"Error Code : " << errorCode << std::endl;
}
return 0;
}
```
`catch` clause can be chained when the expected code might throw multiple type of value.
```c++
try{
test("abcdefg");
} catch (int errorCode) {
std::cout<<"Error Code : " << errorCode << std::endl;
} catch (std::string errorText) {
std::cout<<"Error : " << errorText << std::endl;
}
```
use `catch(...)` to handle the case the type of exception might be unknown.
```c++
try {
test("abcdefg");
} catch (int errorCode) {
std::cout<<"Error Code : " << errorCode << std::endl;
} catch (std::string errorText) {
std::cout<<"Error : " << errorText << std::endl;
} catch (...) {
std::cout<<"Unknown error"<< std::endl;
}
```
# class and Object-Oriented Programming in C++
## Object Oriented Concept Recap
OOC are programming paradigm which the program are represented by relationships between 'objects'. In OO-world, everything is object.
### Class
Objects are classified into classes, which describes the properties of the object that belongs to itself. Properties in OO are attributes (data fields, data members, or properties), and operations (methods, member functions, or subroutine).
### 4 Main Concepts of OOP
Also called '4 pillars of OOP'.
#### Abstraction
*Abstraction* is to model part of the functionality into entities that is easily identifiable by the reader. In OOP, it is basically to group related functionalities into classes.
#### Encapsulation
*Encapsulation* is an ability to limit access to properties to certain groups of related entity. Most programming languages including C++ provides 3 levels of access.
* *public* - The property can be access from any classes.
* *protected* - The property can be access only by the owner and its derived classes.
* *private* - The property can be access only by the owner.
#### Inheritance
*Inheritance* is the relationships between two class. The inheriting classes (derived classes, sub classes, or child classes) have the same properties as the inherited classes (super class, or parent classes).
#### Polymorphism
*Polymorphism* is the ability to display different behavior in the same operation by objects that belongs to the same classes.
For example, objects within the class `Student` are able to `TakeNote()`, but they might do so differently. Some of them might type, some might write, etc.
## Object Oriented in C++
### Class
In C++ class is one way to define user-define data types which is a composite of different data types. To define class, use the keyword `class` follows by name and a pair of curly brackets containing properties of the class.
```c++
class <className> { <classproperties> };
```
The class properties can be variable or functions. This is defined by a very similar syntax to its usual declaration. For example:
```c++
class AClass {
int intProperties;
void someFunction(int parameter) {
print(parameter);
}
};
```
Notice that the class definition ends with `;`.
The function member definition can be moved out of the class, like:
```c++
class AClass {
int intProperties;
void someFunction(int parameter);
};
void AClass::someFunction(int parameter) {
print(parameter);
}
```
And finally, the class definition can be put into a separated header file, just like functions' forward declaration.
**aclass.h**
```c++
#ifndef ACLASS_H
#define ACLASS_H
class AClass {
int intProperties;
void someFunction(int parameter);
};
#endif
```
**aclass.cpp**
```c++
#include "aclass.h"
void AClass::someFunction(int parameter) {
print(parameter);
}
```
### Object Creation
To create an object from a class, declare a variable as usual.
```cpp
WebService service;
```
When the variable is declared, it is initialized right away without any needs to assign anything to it. However if the class accepts parameters during the object initialization, the parameters have to be supplied by a list of value insides a pair of parenthesis.
```cpp
WebService staticHttp(80);
```
Objects can be dynamically created by using `new` operator as well.
```cpp
WebService *staticHttp = new WebService(80);
```
Like other dynamically allocated data, it must be deallocated explicitly using `delete` keyword.
```cpp
delete staticHttp;
```
### Accessing object's properties.
To access a property inside object, use `.` operator. This can be done with both member variable and member functions.
```cpp
std::cout << staticHttp.portNum << ": " <<staticHttp.GetName();
```
Also to access a property of an object via pointer, use `->` operator.
```cpp
WebService staticHttp(80);
WebService *ptr = &staticHttp;
std::cout << ptr->portNum << ": " <<ptr->GetName();
```
Also remember that accessing an un-allowed property results in compilation error. The access level will be discussed next.
## Access level
As mentioned, class is able to limit the access to its members. In C++, the label syntax is used to declared that the properties under the label is either `public`, `protected`, or `private`.
```c++
class AClass {
private:
int intProperties;
public:
void someFunction(int parameter);
protected:
void reservedOperation();
};
```
By default properties are `private`, however we should not relies on the default behavior as it can be confusing.
## Constructor
Constructor is a function-like construct that is called during object's creation. Its main purpose is to initialize the object's member variable.
Constructor can be declared in a very similar way to function with exception of the return type. The constructor's name will be the same as the class name.
```c++
class AClass {
public:
AClass(); //default constructor
AClass(const AClass&); //copy constructor
AClass(int a); // constructor
};
```
There are two specialized kind of constructor in C++, **default contructor** and **copy constructor**. If any of them is not explicitly defined, the compiler will add the missing one automatically. These two will be discussed later.
At constructor's definition, the value of its member variable can be initialized either assignment in the constructor body, or using constructor form after `:` sign just before the constructor body. The constant member can be also assigned this way as well. Any unassigned value will be left at its default value.
```cpp
class WebService {
public:
WebService(int _port);
private:
const int port;
std::vector<Client> client;
std::string hostname;
};
WebService::WebService(int _port): port(_port), hostname(GetHostName())
```
### Default Constructor
**Default constructor** is the constructor that does not takes any parameter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment