[Road to DL Engineer] C++ Tutorial ~Advanced~

こちらの投稿では下記チュートリアルの目次をご覧いただくと記載のある、Advancedのパートを扱うものとします！
それ以降は別の記事にて記載をいたします。

Bear in mind that this post aims to master C++ for beginners.
And most probably containing some mistakes, so please kindly notice me!

Tutorial Link: https://www.tutorialspoint.com/cplusplus/cpp_overview.htm
推薦していただいた参考サイト：http://www.learncpp.com/

Previous post [~Basics~](https://qiita.com/Rowing0914/items/aee5e023d35027682f02)
Previous post [~Object Oriented~](https://qiita.com/Rowing0914/items/05df2d6f82864e65ef2c)

## Content
1. Files and Streams
2. Exception Handling
3. Dynamic Memory
4. Namespaces
5. Template
6. Preprocessor
7. Multithreading

## 1. Files and Streams
There are three types of streaming in C++.
Let's see one by one.
<img width="608" alt="Screen Shot 2018-04-04 at 11.34.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/02edd268-a8ea-f5b7-33be-0810e1e811b0.png">

```C++
#include <fstream>
#include <iostream>
using namespace std;
 
int main () {
   char data[100];

   // open a file in write mode.
   ofstream outfile;
   outfile.open("afile.dat");

   cout << "Writing to the file" << endl;
   cout << "Enter your name: "; 
   cin.getline(data, 100);

   // write inputted data into the file.
   outfile << data << endl;

   cout << "Enter your age: "; 
   cin >> data;
   cin.ignore();
   
   // again write inputted data into the file.
   outfile << data << endl;

   // close the opened file.
   outfile.close();

   // open a file in read mode.
   ifstream infile; 
   infile.open("afile.dat"); 
 
   cout << "Reading from the file" << endl; 
   infile >> data; 

   // write the data at the screen.
   cout << data << endl;
   
   // again read the data from the file and display it.
   infile >> data; 
   cout << data << endl; 

   // close the opened file.
   infile.close();

   return 0;
}

#output
Writing to the file
Enter your name: Norio
Enter your age: 25
Reading from the file
Norio
25
```
and furthermore, we can modify the cursor position in that file.
check this reference: http://www.cplusplus.com/reference/istream/istream/seekg/

## 2. Exception Handling
Exception handling in C++ can be done by three keywords.

- throw : A program throws an exception when a problem shows up. This is done using a throw keyword.
- catch : A program catches an exception with an exception handler at the place in a program where you want to handle the problem. The catch keyword indicates the catching of an exception.
- try : A try block identifies a block of code for which particular exceptions will be activated. It's followed by one or more catch blocks.

```c++
#include <iostream>
using namespace std;

double division(int a, int b){
	if(b == 0){
		throw "Division by 0!";
	}
	return (a/b);
}

int main(){
	int x = 50;
	int y = 0;
	double z = 0;

	try{
		z = division(x,y);
		cout << z << endl;
	}  catch (const char* msg){
		cerr << msg << endl;
	}
	return 0;
}

#output
Division by 0
```
Or if you would like to create your own tailored error, try this!

```c++
#include <iostream>
#include <exception>
using namespace std;

struct MyException : public exception{
	const char* what() const throw() {
		return "C++ Exception";
	}
};

int main(){
	try{
		throw MyException();
	} catch(MyException& e){
		cout << "MyException caught" << endl;
		cout << e.what() << endl;
	}
	return 0;
}

#output
MyException caught
C++ Exception
```

## 3. Dynamic Memory
Understanding of dynamic memory is crucial for good C++ programmer.
Basically it can be classified into two categories below.

- The stack : All variables declared inside the function will take up memory from the stack.
- The heap : This is unused memory of the program and can be used to allocate the memory dynamically when program runs.

And for memory operation, there are two keywords
1. new : assign a memory space to some variables on **heap**
2. delete : deallocate the memory which is created by "new"

Details of memory structure
<img width="669" alt="Screen Shot 2018-04-04 at 12.25.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/eadc1a7e-630c-9f27-1b89-712ebc891325.png">

**Memory operation for Objects**

```c++
#include <iostream>
using namespace std;

class Box {
public:
	Box() {
		cout << "Constructor called!!" << endl;
	}
	~Box(){
		cout << "Destructor called!" << endl;
	}
};

int main(){
	Box* myBoxArray = new Box[10];
	delete [] myBoxArray;
	return 0;
}

#output
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Constructor called!!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
Destructor called!
```

## 4. Namespaces
A namespace is designed to overcome the name conflict and is used as additional information to differentiate similar functions, classes, variables etc. with the same name available in different libraries. Using namespace, you can define the context in which names are defined. In essence, a namespace defines a scope.

```c++
#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

int main () {
   // Calls function from first name space.
   first_space::func();
   
   // Calls function from second name space.
   second_space::func(); 

   return 0;
}
```

## 5. Template
A template is a blueprint or formula for creating a generic class or a function. The library containers like iterators and algorithms are examples of generic programming and have been developed using template concept.

```c++
#include <iostream>
#include <string>

using namespace std;

template <typename T>
inline T const& Max(T const& a, T const& b){
	return a < b ? b : a;
}

int main(){
	int i = 39;
	int j = 20;
	cout << "Max(i, j): " << Max(i, j) << endl;

	double f1 = 13.5; 
	double f2 = 20.7; 
	cout << "Max(f1, f2): " << Max(f1, f2) << endl; 

	string s1 = "Hello"; 
	string s2 = "World"; 
	cout << "Max(s1, s2): " << Max(s1, s2) << endl; 
   
	return 0;
}

#output
Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World
```

**Class Template**
Like as we can define the function template, we could create the template for class as well. Let's try!

```c++
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

using namespace std;

template <class T>
class Stack{
private:
	vector<T> elems;
public:
	void push(T const&);
	void pop();
	T top() const;
	bool empty() const {
		return elems.empty();
	}
};

template <class T>
void Stack<T>::push(T const& elem){
	elems.push_back(elem);
}

template <class T>
void Stack<T>::pop (){
	if(elems.empty()){
		throw out_of_range("Stack<>::pop(): empty stack!!");
	}
	elems.pop_back();
}

template <class T>
T Stack<T>::top() const{
	if(elems.empty()){
		throw out_of_range("Stack<>::top(): empty stack!!");
	}
	return elems.back();
}

int main(){
	try{
		Stack<int> intStack;
		Stack<string> stringStack;

		intStack.push(7);
		cout << intStack.top() << endl;

		stringStack.push("Hello!");
		cout << stringStack.top() << endl;
		stringStack.pop();
		stringStack.pop();
	} catch (exception const& ex){
		cerr << "Exception: " << ex.what() << endl;
		return -1;
	}
}

#output
7
Hello!
Exception: Stack<>::pop(): empty stack!!
```
## 6. Preprocessor
The preprocessors are the directives, which give instructions to the compiler to preprocess the information before actual compilation starts.

**Declaration of variables

```c++
#include <iostream>
using namespace std;

#define PI 3.14159

int main () {
   cout << "Value of PI :" << PI << endl; 

   return 0;
}
```

**Function-like Macro**

```c++
#include <iostream>
using namespace std;

#define MIN(a,b) (((a)<(b)) ? a : b)

int main () {
   int i, j;
   
   i = 100;
   j = 30;
   
   cout <<"The minimum is " << MIN(i, j) << endl;

   return 0;
}
```
**Conditional Compilation**

```c++
#include <iostream>
using namespace std;
#define DEBUG

#define MIN(a,b) (((a)<(b)) ? a : b)

int main () {
   int i, j;
   
   i = 100;
   j = 30;

#ifdef DEBUG
   cerr <<"Trace: Inside main function" << endl;
#endif

#if 0
   /* This is commented part */
   cout << MKSTR(HELLO C++) << endl;
#endif

   cout <<"The minimum is " << MIN(i, j) << endl;

#ifdef DEBUG
   cerr <<"Trace: Coming out of main function" << endl;
#endif

   return 0;
}
```

**Pre-defined Macros**
<img width="611" alt="Screen Shot 2018-04-06 at 11.23.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/b2885324-b4fc-d56f-be99-2ca83ea4bc2d.png">

```c++
#include <iostream>
using namespace std;

int main () {
   cout << "Value of __LINE__ : " << __LINE__ << endl;
   cout << "Value of __FILE__ : " << __FILE__ << endl;
   cout << "Value of __DATE__ : " << __DATE__ << endl;
   cout << "Value of __TIME__ : " << __TIME__ << endl;

   return 0;
}
```
## 7. Multithreading
Multithreading is a specialized form of multitasking and a multitasking is the feature that allows your computer to run two or more programs concurrently. In general, there are two types of multitasking: process-based and thread-based.

**params for pthread_create function**
<img width="610" alt="Screen Shot 2018-04-06 at 11.46.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/53f476e6-9698-df6c-9441-96a0565aa2b5.png">

This simple example code creates 5 threads with the pthread_create() routine. Each thread prints a "Hello World!" message, and then terminates with a call to pthread_exit().

```c++
#include <iostream>
#include <cstdlib>
#include <cstdint>
#include <pthread.h>

using namespace std;

#define NUM_THREADS 5

void *PrintHello(void *threadid) {
   long tid;
   tid = (long)threadid;
   cout << "Hello World! Thread ID, " << tid << endl;
   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   int rc;
   int i;
   
   for( i = 0; i < NUM_THREADS; i++ ) {
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&i);
      
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}

#output
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Hello World! Thread ID, 140734620830360
Hello World! Thread ID, 140734620830360
Hello World! Thread ID, 140734620830360
Hello World! Thread ID, 140734620830360
Hello World! Thread ID, 140734620830360
```

**Passing Arguments to Multithread**

```c++
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <string>

using namespace std;

#define NUM_THREADS 5

struct thread_data {
   int  thread_id;
   string message;
};

void *PrintHello(void *threadarg) {
   struct thread_data *my_data;
   my_data = (struct thread_data *) threadarg;

   cout << "Thread ID : " << my_data->thread_id ;
   cout << " Message : " << my_data->message << endl;

   pthread_exit(NULL);
}

int main () {
   pthread_t threads[NUM_THREADS];
   struct thread_data td[NUM_THREADS];
   int rc;
   int i;

   for( i = 0; i < NUM_THREADS; i++ ) {
      cout <<"main() : creating thread, " << i << endl;
      td[i].thread_id = i;
      td[i].message = "This is message";
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
      
      if (rc) {
         cout << "Error:unable to create thread," << rc << endl;
         exit(-1);
      }
   }
   pthread_exit(NULL);
}
```