#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;
}