独習C++ 2章続き

#2.2 クラス概要
```
#include <iostream>

class product{
   int id;
   int price;
   int stock;
   
   public:
      int get_id();
      void set_id(int new_id);

      int get_price();
      void set_price(int new_price);
      int get_stock();
      void set_stock(int new_stock);
};

int product::get_id(){
   return id;
}

void product::set_id(int new_id){
   id = new_id;
}

int product::get_price(){
   return price;
}

void product::set_price(int new_price){
   if(new_price < 0){
      std::cout << "error" << std::endl;
      return;
   }
   price = new_price;
}

int product::get_stock(){
   return stock;
}

void product::set_stock(int new_stock){
   if(new_stock < 0){
      std::cout << "error"<< std::endl;
   }
   stock = new_stock;
}

int main(){
   product pen;

   pen.set_id(0);
   pen.set_price(100);
   pen.set_stock(200);

   product* ptr = &pen;
   std::cout << ptr->get_id() << std::endl;
   std::cout << ptr->get_price() << std::endl;
   std::cout << ptr->get_stock() << std::endl;
}
```

## 2.3 参照
```
#include <iostream>

int main(){
   int value = 42;
   std::cout << &value << std::endl;

   int & reference = value;
   std::cout << reference << std::endl;
   reference = 0;
   std::cout << &value << std::endl;
}

-> 

0x16dc1f244
42
0x16dc1f244

```

再代入されても、変数のアドレスは変わらない。

### 2.3.2 the difference between reference and pointer

```
#include <iostream>

int main(){
   int value = 42;
   int other = 0;
   int const*pointer  = &value;
   int &reference = value;
   std::cout << "value's address" << &value << std::endl;
   std::cout << "other's address "  << &other << std::endl;
   std::cout << "pointer's address "  << pointer << std::endl;
   std::cout << "reference's address "  << &reference << std::endl;

   pointer = &other;
   reference = other;
   std::cout << std::endl;

   std::cout << "other's address " << &other << std::endl;
   std::cout << "pointer's address " << pointer << std::endl;
   std::cout << "reference's address " << &reference << std::endl;

}

value's address0x16dbd323c
other's address 0x16dbd3238
pointer's address 0x16dbd323c
reference's address 0x16dbd323c

other's address 0x16dbd3238
pointer's address 0x16dbd3238
reference's address 0x16dbd323c
```

if we use reference, we cannot reassign reference.

### 2.3.3 const reference
```
#include <iostream>

int main(){
   int value = 42;
   int &reference = value;
   const int & creference = value;

   value = 0;
   reference = 0; // ok
   creference = 0; // error
}
```

## 2.4 auto
```
#include <iostream>

int one (){
   return 1;
}

int main(){
   int arr[] = {1,2,3,4,5};
   for(auto i : arr){
      std::cout << i << std::endl;
   }
}
```

### 2.4.3 decltype
decltype can estimate the type from expression.

```
#include <iostream>

decltype(1) one(){
   return 1;
}

int main(){
   auto i = one();
   decltype(i) j;

   j = 42.195;
   std::cout << j << std::endl;
}
```

## 2.5 alias of type
```
#include <iostream>

using integer = int;
integer main(){
   int value = 42;
   using number = integer;
   number num = 0;
   value = num;
}
```

### 2.5.2 nester type
```
#include <iostream>

class data {
   public:
      using integer = int;

      integer get_value();
      void set_value(integer new_value);

   private:
      integer value;
};

data::integer data::get_value(){
   return value;
}

void data::set_value(integer new_value){
   // inside member variable, it is regarded as class, so we do not need ::
   integer tmp = new_value;
   value = tmp;
}

int main(){
   data d;
   using integer = data::integer;
   integer value = 42;

   d.set_value(value);
   std::cout << d.get_value() << std::endl;
}
```

To use type defined in class out of class, we have to use `::`.

### 2.6.2 std::cin
```
#include <iostream>
#include <string>

using integer = int;
integer main(){
   using in = integer;
   std::string s;
   std::cout << "input string ";
   std::getline(std::cin, s);
   std::cout << "input string is " << s << std::endl;
}
```

- std::getline(std::cin, s)
```
#include <iostream>
#include <string>

using integer = int;
integer main()
{
   while (1)
   {
      std::string s;
      std::getline(std::cin, s);
      if(s != " "){
         std::cout << s << std::endl;
      }
      else{
         break;
      }
   }
}
```

# 2.7 関数のオーバーロード
```
#include <iostream>

void show_value(int a){
   std::cout << a << std::endl;
}

int sum(int a, int b, int c){
   return a + b + c;
}

int sum(int a, int b){
   return a + b;
}

int main(){
   int x = sum(10, 20);
   show_value(x);

   int y = sum(10,20,30);
   show_value(y);
}
```

```
#include <iostream>

struct vector2d {
   float x;
   float y;
};

float sub(float a, float b){
   return a - b;
}

vector2d sub(vector2d a, vector2d b){
   vector2d c = {sub(a.x, b.x), sub(a.y , b.y)};
   return c;
}

int main(){
   std::cout << sub(10, 20) << std::endl;
   vector2d a = {10,20};
   vector2d b = {20,30};
   auto v = sub(a, b);
   std::cout << v.x << ", " << v.y << std::endl;
}
```

## 2.8 ラムダ式
```
#include <iostream>

int main(){
   auto show = [](int i) -> void {
      std::cout << i << std::endl;
   };
   show(42);
}
```

The return type must be `auto`. because lambda expression is an unique object which compiler creates automatically.

```
#include <iostream>

int main(){
   int a = 0;

   auto lambda = [a]()->void {
      std::cout << a << std::endl;
   };
   a = 42;
   lambda();
}

-> 0
```

lambda expression's `a` is captured when this is defined.

If we use `=`, compiler capture the variable inside lambda automatically. 
```
#include <iostream>

int main(){
   int a = 0;

   float b = 3.14f;
   auto lambda = [=](){
      std::cout << a << std::endl;
   };

   lambda();
}

```

```
#include <iostream>

int main(){
   int a = 0;

   float b = 3.14f;
   auto lambda = [a]() mutable{
      a = 42;
      std::cout << a << std::endl;
   };

   lambda();
   std::cout << a << std::endl;
}

42
0

```

If we want to make captured variables mutable, we should add `mutable` because the captured variables are default `const`.

reference capture
```
#include <iostream>

int main(){
   int a = 0;

   auto lambda = [&a](){
      std::cout << "captured variable " << a << std::endl;
      ++a;
   };
   lambda();

   std::cout << a << std::endl;

   a = 42;

   lambda();
}
```

We can specify copy or reference individually.
```
#include <iostream>

int main(){
   int copy = 42;
   int ref = 0;

   auto lambda = [&, copy](){
      ++ref;
   };
   lambda();
   std::cout << ref << std::endl;
}

```