CPP - soup1997/Study-Alone GitHub Wiki

Namespace

namespace๋ž€ ์–ด๋–ค ์ •์˜๋œ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์–ด๋””์— ์†Œ์†๋˜์–ด์žˆ๋Š”์ง€ ์ง€์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธ

namespace header1 {
 int foo();
 void bar();
}

namespace header2 {
 int foo();
 void bar();

int main() {
 header1::foo();
 header2::foo();
}
using namespace std;

์œ„์™€ ๊ฐ™์ด ์–ด๋– ํ•œ ์ด๋ฆ„๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋ผ๊ณ  ์„ ์–ธํ•˜๋Š” ๊ฒƒ์€ ๊ถŒ์žฅ๋˜์ง€ ์•Š์Œ. std::๋ฅผ ์ง์ ‘ ์•ž์— ๋ถ™์—ฌ std์˜ namespace์˜ ํ•จ์ˆ˜์ด๋‹ค๋ผ๊ณ  ๋ช…์‹œํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹์Œ

Reference

C์–ธ์–ด์—์„œ๋Š” ์–ด๋– ํ•œ ๋ณ€์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์‹ถ์„ ๋• ๋ฐ˜๋“œ์‹œ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•จ. C++์—์„œ๋Š” ๋‹ค๋ฅธ ๋ณ€์ˆ˜๋‚˜ ์ƒ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ฐธ์กฐ์ž(reference)๋ฅผ ์ œ๊ณตํ•จ.
ํ•จ์ˆ˜์—์„œ call by reference๋กœ ์ธ์ž๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ  ํฌ์ธํ„ฐ์ฒ˜๋Ÿผ ์ง์ ‘ ์ฐธ์กฐ๋ฅผ ํ•˜๊ธฐ์— ๋น ๋ฅด๋‹ค.

void print_array(const std::array<int, 5>& arr)์™€ ๊ฐ™์ด ์‚ฌ์šฉ๊ฐ€๋Šฅ

int main() {
 int a = 3;
 int& another_a = a;

 int arr[3] = {1, 2, 3};
 int(&ref)[3] = arr;
}

another_a๋Š” a์˜ ๋˜๋‹ค๋ฅธ ์ด๋ฆ„์ด๋ผ๊ณ  ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฃผ์˜ํ•  ์ ์€ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ํ•œ๋ฒˆ ๋ณ„๋ช…์ด ๋˜๋ฉด ์ ˆ๋Œ€๋กœ ๋‹ค๋ฅธ ์ด์˜ ๋ณ„๋ช…์ด ๋  ์ˆ˜ ์—†๋‹ค.
๋”ฐ๋ผ์„œ ๋ช…์‹œํ•  ์ ์€ ์ดˆ๊ธฐํ™”์™€ ๋™์‹œ์— ์ฐธ์กฐ์ž๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ๋ฐฐ์—ด์„ reference๋กœ ์ง€์ •ํ•  ๊ฒฝ์šฐ ref[0]๋ถ€ํ„ฐ ref[2]๊ฐ€ ๊ฐ๊ฐ arr[0]๋ถ€ํ„ฐ arr[2]์˜ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋œ๋‹ค.

int& function(int &a) {
 a = 5;
 return a;
}

int main() {
 int b = 2;
 int c = function(b);
 return 0;
}

function(b)๋ฅผ ์‹คํ–‰ํ•œ ์‹œ์ ์—์„œ a๋Š” main์˜ b๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ function์ด ๋ฆฌํ„ดํ•œ ์ฐธ์กฐ์ž๋Š” ์•„์ง ์‚ด์•„์žˆ๋Š” ๋ณ€์ˆ˜์ธ b๋ฅผ ๊ณ„์† ์ฐธ์กฐํ•œ๋‹ค.
๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ํƒ€์ž…์˜ ํฌ๊ธฐ์™€ ์ƒ๊ด€์—†์ด ๋”ฑ ํ•œ๋ฒˆ์˜ ์ฃผ์†Œ๊ฐ’ ๋ณต์‚ฌ๋กœ ์ „๋‹ฌ์ด ๋๋‚˜๊ฒŒ ๋œ๋‹ค.

Dynamic Allocate

T* pointer = new T[size]

int main() {
 int arr_size;

 std::cout << "array size : ";
 std::cin >> arr_size;

 int *list = new int[arr_size];

 delete[] list;
}

ํฌ์ธํ„ฐ ๋ณ€์ˆ˜ list์— ์›ํ•˜๋Š” datatype์˜ size๋งŒํผ ํ• ๋‹นํ•ด์ฃผ๋ฉด ๋œ๋‹ค. ๊ตฌ์กฐ์ฒด๋ฅผ ๋™์ ํ• ๋‹น ํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด์ž.

typedef struct Animal {
 char name[30];
 int age;
 int health;
 int food;
 int clean;
} Animal;

int main() {
 int num;
 Animal *list[10];
 
 std::cin >> num;
 list[num] = new Animal;
}

Class

#include <iostream>

class Marine {
private:
	static int total_marine_num; // ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ํ•˜๋‚˜์˜ static ๋ณ€์ˆ˜
	int hp;
	int coord_x, coord_y;
	bool is_dead;

	const int default_damage;

public:
	Marine();
	Marine(int x, int y);
	Marine(int x, int y, int default_damage);

	int attack();
	void be_attacked(int damage_earn);
	void move(int x, int y);

	void show_status();
	static void show_total_marine(); // ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ณต์œ ํ•˜๋Š” ํ•˜๋‚˜์˜ static ํ•จ์ˆ˜

	~Marine();
};


// Static variable, method, initialization
int Marine::total_marine_num = 0;
void Marine::show_total_marine() {
	std::cout << "์ „์ฒด ๋งˆ๋ฆฐ ์ˆ˜: " << total_marine_num << std::endl;
}

// Initializer list
// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ๊ณผ ์ดˆ๊ธฐํ™”๋ฅผ ๋™์‹œ์— ์ˆ˜ํ–‰
// reference ๋ณ€์ˆ˜๋‚˜, const ๋ณ€์ˆ˜๋Š” ์ƒ์„ฑ๊ณผ ๋™์‹œ์— ์ดˆ๊ธฐํ™”๊ฐ€ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•จ
// ๋”ฐ๋ผ์„œ ์ดˆ๊ธฐํ™” ๋ฆฌ์ŠคํŠธ๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜๋“ค์— ๋Œ€ํ•ด ํŠนํ™”๋œ ๋ฐฉ์‹์ด๋ผ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

Marine::Marine()
	: hp(50), coord_x(0), coord_y(0), default_damage(5), is_dead(false) {
	total_marine_num++;
}

Marine::Marine(int x, int y)
	: coord_x(x), coord_y(y), hp(50), default_damage(5), is_dead(false) {
	total_marine_num++;
}

Marine::Marine(int x, int y, int default_damage)
	: coord_x(x), coord_y(y), hp(50), default_damage(default_damage), is_dead(false) {
	total_marine_num++;
}

Marine::~Marine() {
	total_marine_num--;
}

void Marine::move(int x, int y) {
	coord_x = x;
	coord_y = y;
}

int Marine::attack() {
	return default_damage;
}

void Marine::be_attacked(int damage_earn) {
	hp -= damage_earn;
	if (hp < 0) is_dead = true;
}

void Marine::show_status() {
	std::cout << " *** Marine ***" << std::endl;
	std::cout << " Location : ( " << coord_x << " , " << coord_y << " ) ";
	std::cout << " HP : " << hp << std::endl;
	std::cout << " ํ˜„์žฌ ์ด ๋งˆ๋ฆฐ ์ˆ˜: " << total_marine_num << std::endl;
}

void create_marine() {
	Marine marine3(10, 10, 4);
	Marine::show_total_marine();
}

int main() {
	Marine marine1(2, 3, 5);
	Marine::show_total_marine(); // ์–ด๋– ํ•œ ๊ฐ์ฒด๋„ ์ด ํ•จ์ˆ˜๋ฅผ ์†Œ์œ ํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— (ํด๋ž˜์Šค)::(static ํ•จ์ˆ˜)๋กœ ์ ‘๊ทผ

	Marine marine2(3, 5, 10);
	Marine::show_total_marine();

	create_marine();

	std::cout << std::endl << "๋งˆ๋ฆฐ 1์ด ๋งˆ๋ฆฐ 2๋ฅผ ๊ณต๊ฒฉ !" << std::endl;
	marine2.be_attacked(marine1.attack());

	marine1.show_status();
	marine2.show_status();
}

private: ๊ฐ์ฒด ๋ฐ–์—์„œ ์ธ์œ„์ ์œผ๋กœ ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅ, ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ๋งŒ ์ด์šฉ๊ฐ€๋Šฅ ๋ณ€์ˆ˜, ๋ฉ”์„œ๋“œ
public: private์˜ ํŠน์ง•๊ณผ ์ •๋ฐ˜๋Œ€
์ฐธ๊ณ ๋กœ ํ‚ค์›Œ๋“œ ๋ช…์‹œ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ private์œผ๋กœ ์ง€์ •๋œ๋‹ค.

Static Variable, Method in Class

static ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์˜ ๊ฒฝ์šฐ, ํด๋ž˜์Šค์˜ ๋ชจ๋“  ๊ฐ์ฒด๋“ค์ด '๊ณต์œ 'ํ•˜๋Š” ๋ณ€์ˆ˜๋กœ์จ ๋‹ค๋กœ ์กด์žฌํ•˜๋Š” ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค๊ณผ๋Š” ๋‹ฌ๋ฆฌ ๋ชจ๋“  ๊ฐ์ฒด๋“ค์ด 'ํ•˜๋‚˜์˜' static๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.
๋ชจ๋“  ์ „์—ญ ๋ฐ static ๋ณ€์ˆ˜๋“ค์€ ์ •์˜์™€ ๋™์‹œ์— ๊ฐ’์ด ์ž๋™์œผ๋กœ 0์œผ๋กœ ์ดˆ๊ธฐํ™” ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ๊ตณ์ด ์ดˆ๊ธฐํ™” ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.
๋˜ํ•œ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋“ค์€ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

int Marine::total_marin_num = 0;

static ํ•จ์ˆ˜๋Š” ์–ด๋–ค ๊ฐ์ฒด์— ์ข…์†๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค์— ์ข…์†๋˜๋Š” ๊ฒƒ์œผ๋กœ, ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ (๊ฐ์ฒด).(๋ฉค๋ฒ„ ํ•จ์ˆ˜)๊ฐ€ ์•„๋‹ˆ๋ผ ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ•œ๋‹ค.

Marine::show_total_marine();

This

Marine& Marine::be_attacked(int damage_earn) {
	hp -= damage_earn; // this->hp = damage_earn; ๋„ ๊ฐ€๋Šฅ
	if (hp <= 0) is_dead = true; // if (this->hp <= 0) this->is_dead = true;

	return *this;
}

this->hp = damage_earn;๋Š” ์ด ๋ฉค๋ฒ„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฐ์ฒด ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ
be_attacked()ํ•จ์ˆ˜๋Š” Marine&์„ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์œ„์˜ ๊ฒฝ์šฐ *this๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๊ฒƒ์€ ๊ทธ ๊ฐ์ฒด ์ž์‹ ์„ ์˜๋ฏธํ•˜๊ฒŒ ๋œ๋‹ค.

๋งŒ์ผ be_attacked()์˜ ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์ด Marine&์ด ์•„๋‹ˆ๋ผ Marine์ด๋ผ๋ฉด ์ž„์‹œ ๊ฐ์ฒด Marine์„ ์ƒ์„ฑํ•ด์„œ, *this์˜ ๋‚ด์šฉ์œผ๋กœ ๋ณต์‚ฌ๊ฐ€ ๋˜๊ณ  ์ด ์ž„์‹œ ๊ฐ์ฒด์— ๋Œ€ํ•œ be_attacked()ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

Operator Overloading

:: (๋ฒ”์œ„ ์ง€์ •), . (๋ฉค๋ฒ„ ์ง€์ •), .*(๋ฉค๋ฒ„ ํฌ์ธํ„ฐ๋กœ ๋ฉค๋ฒ„ ์ง€์ •)์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์—ฐ์‚ฐ์ž๋ฅผ ์˜ค๋ฒ„๋กœ๋”ฉ ๊ฐ€๋Šฅ\

(๋ฆฌํ„ด ํƒ€์ž…) operator(์—ฐ์‚ฐ์ž) (์—ฐ์‚ฐ์ž๊ฐ€ ๋ฐ›๋Š” ์ธ์ž)

class Mystring {
private:
 char* string_content;
 int string_length;

public:
 bool operator==(Mystring &str);
}

bool Mystring::operator==(Mystring &str) {
 return !compare(str);
}

์ฒจ์ž ์—ฐ์‚ฐ์ž (operator [])

char& Mystring::operator[](const int index) {
 return string_content[index];
}

C++ Casting

์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์ž๋™์œผ๋กœ ์บ์ŠคํŒ… ํ•ด์ฃผ๋Š” ์•”์‹œ์ (implicit) ์บ์ŠคํŒ…๊ณผ, ์ง์ ‘ ์บ์ŠคํŒ…์„ ์ง€์ •ํ•ด์ฃผ๋Š” ๋ช…์‹œ์ (explicit) ์บ์ŠคํŒ…์ด ์กด์žฌ
c++์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ 4๊ฐœ์˜ ์บ์ŠคํŒ…์„ ์ง€์›ํ•œ๋‹ค. ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ๊ฒŒ ๋˜๋Š”๊ฒƒ์€ ๊ฐ€์žฅ ์œ„์˜ 2๊ฐœ ๋‚˜๋จธ์ง„ ๊ฑฐ์˜ ์ด์šฉX

  • static_cast: ์–ธ์–ด์  ์ฐจ์›์—์„œ ์ง€์›ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ํƒ€์ž… ๋ณ€ํ™˜
  • const_cast: ๊ฐ์ฒด์˜ ์ƒ์ˆ˜์„ฑ(const)๋ฅผ ์—†์• ๋Š” ํƒ€์ž… ๋ณ€ํ™˜, const int๊ฐ€ int๋กœ ๋ณ€๊ฒฝ๋จ
  • dynamic_cast: ํŒŒ์ƒ ํด๋ž˜์Šค ์‚ฌ์ด์—์„œ์˜ ๋‹ค์šด ์บ์ŠคํŒ…
  • reinterpret_cast: ์œ„ํ—˜์„ ๊ฐ์ˆ˜ํ•˜๊ณ  ํ•˜๋Š” ์บ์ŠคํŒ…์œผ๋กœ ์„œ๋กœ ๊ด€๋ จ์ด ์—†๋Š” ํฌ์ธํ„ฐ๋“ค ์‚ฌ์ด์˜ ์บ์ŠคํŒ…

์•„๋ž˜์˜ ์ฝ”๋“œ๋Š” ์™„์ „ํžˆ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.

static_cast<int>(float_variable);
(int)(float_variable);

Class Inheritance

class Derived: public Base {
private:
 std::string s;

public:
 Derived(): Base(), s("ํŒŒ์ƒ") {
  std::cout << "ํŒŒ์ƒ ํด๋ž˜์Šค" << std::endl;
 }
}

์œ„์˜ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ƒ์†์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฃผ์˜ํ•  ์ ์€ Derived์˜ ์ƒ์„ฑ์ž๋Š” ์œ„ ์ฒ˜๋Ÿผ ์ดˆ๊ธฐํ™”์ž ๋ฆฌ์ŠคํŠธ์—์„œ ๊ธฐ๋ฐ˜์˜ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์„œ ๊ธฐ๋ฐ˜์˜ ์ƒ์„ฑ์„ ๋จผ์ € ์ฒ˜๋ฆฌ ํ•œ ๋‹ค์Œ์—, Derived์˜ ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.

#include <iostream>
#include <string>
#pragma warning(disable:4996)


// virtual, overide

class Employee {
	// Manager ํด๋ž˜์Šค์—์„œ ์ƒ์†๋ฐ›์•„ ์ ‘๊ทผํ•ด์•ผ ํ•˜๋ฏ€๋กœ private ํ‚ค์›Œ๋“œ๋กœ ์ง€์ •ํ•˜๋ฉด ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅ
protected:
	std::string name;
	int age;

	std::string position;
	int rank;

public:
	Employee(std::string name, int age, std::string position, int rank) : name(name), age(age), position(position), rank(rank) {}

	Employee(const Employee& employee) {
		name = employee.name;
		age = employee.age;
		position = employee.position;
		rank = employee.rank;
	}

	Employee() {}

	// vitual: ๊ฐ€์ƒ ํ•จ์ˆ˜, ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ virtual ํ‚ค์›Œ๋“œ์˜ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜(์˜ค๋ฒ„๋ผ์ด๋”ฉ)ํ•œ๋‹ค๋Š” ๋œป
	virtual void print_info() {
		std::cout << name << " (" << position << " , " << age << ") ==>" << calculate_pay() << "๋งŒ์›" << std::endl;
	}

	virtual int calculate_pay() {
		return 200 + rank * 50;
	}
};

class Manager : public Employee {
private:
	int year_of_service;

public:
	Manager(std::string name, int age, std::string position, int rank, int year_of_service) : Employee(name, age, position, rank), year_of_service(year_of_service) {}

	// override: virtual๊ณผ ๋˜‘๊ฐ™์€ ๊ธฐ๋Šฅ, ๋‹ค๋งŒ ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด๋Š” ์œ„์น˜๊ฐ€ ๋‹ค๋ฆ„(ํ•จ์ˆ˜ ์ด๋ฆ„ ๋’ค์—), ์ด ๊ฐ€์ƒํ•จ์ˆ˜๊ฐ€ ์ƒ์†๋ฐ›์•„์„œ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ ํ•จ์ˆ˜๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•จ
	int calculate_pay() override{
		return 200 + rank * 50 + 5 * year_of_service;
	}

	void print_info() override{
		std::cout << name << " (" << position << " , " << age << " , "
			<< year_of_service << "๋…„์ฐจ) ==> " << calculate_pay() << "๋งŒ์›" << std::endl;
	}
};

class EmployeeList {
private:
	int alloc_employee;
	int current_employee;

	Employee** employee_list;

public:
	EmployeeList(int alloc_employee) : alloc_employee(alloc_employee) {
		employee_list = new Employee* [alloc_employee];
		current_employee = 0;
	}

	void add_employee(Employee* employee) {
		employee_list[current_employee] = employee;
		current_employee++;
	}

	int current_employee_num() {
		return current_employee;
	}

	void print_employee_info() {
		int total_pay = 0;

		for (int i = 0; i < current_employee; i++) {
			employee_list[i]->print_info();
			total_pay += employee_list[i]->calculate_pay();
		}

		std::cout << "์ด ๋น„์šฉ: " << total_pay << "๋งŒ์›" << std::endl;
	}

	~EmployeeList() {
		for (int i = 0; i < current_employee; i++) {
			delete employee_list[i];
		}

		delete[] employee_list;
	}
};

int main() {
	EmployeeList emp_list(10);

	emp_list.add_employee(new Employee("๋…ธํ™์ฒ ", 34, "ํ‰์‚ฌ์›", 1));
	emp_list.add_employee(new Employee("ํ•˜๋™ํ›ˆ", 34, "ํ‰์‚ฌ์›", 1));
	emp_list.add_employee(new Manager("์œ ์žฌ์„", 41, "๋ถ€์žฅ", 7, 12));
	emp_list.add_employee(new Manager("์ •์ค€ํ•˜", 43, "๊ณผ์žฅ", 4, 15));
	emp_list.add_employee(new Manager("๋ฐ•๋ช…์ˆ˜", 43, "์ฐจ์žฅ", 5, 13));
	emp_list.add_employee(new Employee("์ •ํ˜•๋ˆ", 36, "๋Œ€๋ฆฌ", 2));
	emp_list.add_employee(new Employee("๊ธธ์„ฑ์ค€", 36, "์ธํ„ด", -1));

	emp_list.print_employee_info();

	return 0;
}
  • protected: public๊ณผ private์— ์ค‘๊ฐ„ ์œ„์น˜์— ์žˆ๋Š” ์ ‘๊ทผ ์ง€์‹œ์ž, ์ƒ์†๋ฐ›๋Š” ํด๋ž˜์Šค์—์„œ๋Š” ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ณ  ๊ทธ ์™ธ์˜ ๊ธฐํƒ€ ์ •๋ณด๋Š” ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅ
  • virtual: virtual ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ƒ ํ•จ์ˆ˜(virtual function)์ด๋ผ๊ณ  ์นญํ•จ. ์ฆ‰, ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š” ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ ํ•ด๋‹น ํ‚ค์›Œ๋“œ์˜ ํ•จ์ˆ˜๋ฅผ ์žฌ์ •์˜(์˜ค๋ฒ„๋ผ์ด๋”ฉ)ํ•œ๋‹ค๋Š” ๋œป
  • override: ํŒŒ์ƒ ํด๋ž˜์Šค์—์„œ ๊ธฐ๋ฐ˜ ํด๋ž˜์Šค์˜ ๊ฐ€์ƒ ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜๋Š” ๊ฒฝ์šฐ, overrideํ‚ค์›Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ์Œ

virtual ์†Œ๋ฉธ์ž

#include <iostream>

class Parent {
public:
	Parent() { std::cout << "Parent ์ƒ์„ฑ์ž ํ˜ธ์ถœ" << std::endl; }
	~Parent() { std::cout << "Parent ์†Œ๋ฉธ์ž ํ˜ธ์ถœ" << std::endl; }
};

class Child : public Parent {
public:
	Child() { std::cout << "Child ์ƒ์„ฑ์ž ํ˜ธ์ถœ" << std::endl; }
	~Child() { std::cout << "Child ์†Œ๋ฉธ์ž ํ˜ธ์ถœ" << std::endl; }
};


int main() {
	std::cout << "--- ํ‰๋ฒ”ํ•œ Child๋ฅผ ๋งŒ๋“ค์—ˆ์„๋•Œ ---" << std::endl;
	{Child C; }

	std::cout << "--- Parent ํฌ์ธํ„ฐ๋กœ Child๋ฅผ ๊ฐ€๋ฆฌ์ผฐ์„ ๋•Œ ---" << std::endl;
	{Parent* p = new Child;
	delete p; }

	return 0;
}
--- ํ‰๋ฒ”ํ•œ Child๋ฅผ ๋งŒ๋“ค์—ˆ์„๋•Œ ---
Parent ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์†Œ๋ฉธ์ž ํ˜ธ์ถœ
Parent ์†Œ๋ฉธ์ž ํ˜ธ์ถœ
--- Parent ํฌ์ธํ„ฐ๋กœ Child๋ฅผ ๊ฐ€๋ฆฌ์ผฐ์„ ๋•Œ ---
Parent ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Parent ์†Œ๋ฉธ์ž ํ˜ธ์ถœ

Parent ํฌ์ธํ„ฐ๊ฐ€ Child ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ๋•Œ delete p๋ฅผ ํ•˜๋”๋ผ๋„, p๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒ์€ Parent ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ Child ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์—, ์œ„์—์„œ ๋ณดํ†ต์˜ Child ๊ฐ์ฒด๊ฐ€ ์†Œ๋ฉธ๋˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ƒ์„ฑ์ž์™€ ์†Œ๋ฉธ์ž๋“ค์ด ํ˜ธ์ถœ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š”, Child ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋Š” ๊ณง ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(memory leakage)๋ฌธ์ œ๋กœ ๋ฐœ์ƒํ•œ๋‹ค. ๋”ฐ๋ผ์„œ Parent์˜ ์†Œ๋ฉธ์ž๋ฅผ virtual๋กœ ๋งŒ๋“ค๋ฉด, p๊ฐ€ ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, Child์˜ ์†Œ๋ฉธ์ž๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

virtual ~Parent() { std::cout << "Parent ์†Œ๋ฉธ์ž ํ˜ธ์ถœ" << std::endl; }
--- ํ‰๋ฒ”ํ•œ Child๋ฅผ ๋งŒ๋“ค์—ˆ์„๋•Œ ---
Parent ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์†Œ๋ฉธ์ž ํ˜ธ์ถœ
Parent ์†Œ๋ฉธ์ž ํ˜ธ์ถœ
--- Parent ํฌ์ธํ„ฐ๋กœ Child๋ฅผ ๊ฐ€๋ฆฌ์ผฐ์„ ๋•Œ ---
Parent ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์ƒ์„ฑ์ž ํ˜ธ์ถœ
Child ์†Œ๋ฉธ์ž ํ˜ธ์ถœ
Parent ์†Œ๋ฉธ์ž ํ˜ธ์ถœ

์ด๋Š” Child์˜ ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด์„œ, Child ์†Œ๋ฉธ์ž๊ฐ€ ์•Œ์•„์„œ Parent์˜ ์†Œ๋ฉธ์ž๋„ ํ˜ธ์ถœํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ฒฐ๊ตญ virtualํ‚ค์›Œ๋“œ๋Š” Child๋Š” Parent์—์„œ ์ƒ์†๋ฐ›์•˜๋‹ค๋Š” ๊ฒƒ์„ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ๋ช…์‹œ์ ์œผ๋กœ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

์ด์™€ ๊ฐ™์€ ์ด์œ ๋กœ, ์ƒ์†๋  ์—ฌ์ง€๊ฐ€ ์žˆ๋Š” Base ํด๋ž˜์Šค๋“ค์€ ๋ฐ˜๋“œ์‹œ ์†Œ๋ฉธ์ž๋ฅผ virtual๋กœ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ ๋‚˜์ค‘์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์—ฌ์ง€๊ฐ€ ์—†๊ฒŒ ๋œ๋‹ค.

Multiple Inheritance

class A {
public:
 int a;
};

class B {
public:
 int b;
};

class C: public A, public B {
public:
 int c;
};

A -> B -> C์˜ ์ˆœ์„œ๋กœ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

Standard I/O Library

operator >>์˜ ํŠน์ง•์œผ๋กœ, ๋ชจ๋“  ๊ณต๋ฐฑ๋ฌธ์ž (๋„์–ด์“ฐ๊ธฐ๋‚˜ ์—”ํ„ฐ, ํƒญ ๋“ฑ)์„ ์ž…๋ ฅ์‹œ์— ๋ฌด์‹œํ•ด ๋ฒ„๋ฆฐ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—, ๋งŒ์ผ cin์„ ํ†ตํ•ด์„œ ๋ฌธ์žฅ์„ ์ž…๋ ฅ ๋ฐ›๋Š” ๋‹ค๋ฉด, ์ฒซ ๋‹จ์–ด๋งŒ ์ž…๋ ฅ๋ฐ›๊ณ  ๋‚˜๋จธ์ง€๋ฅผ ์ฝ์„ ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ std::getline(string)์„ ํ™œ์šฉํ•œ๋‹ค.

// ์ง€์ •ํ•œ delimiter๋ฅผ ๋งŒ๋‚˜๊ธฐ ์ „๊นŒ์ง€ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ์ฝ์–ด์„œ string ๊ฐ์ฒด์— ์ €์žฅ (๋””ํดํŠธ ๊ตฌ๋ถ„์ž๋Š” ๊ฐœํ–‰ ๋ฌธ์ž)
getline(istream& is, string str);
getline(istream& is, string str, char dlim);
string s;
cin.ignore(); //์ž…๋ ฅ ๋ฒ„ํผ ๋น„์šฐ๊ธฐ
getline(std::cin, s); // ํŠน์ • ๋ฌธ์ž๊ฐ€ ๋‚˜์˜ฌ๋•Œ๊นŒ์ง€ ์ž…๋ ฅ๋ฐ›์Œ, dlim์˜ default๋Š” "\n"

Template

์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ํƒ€์ž…์„ ๋„ฃ์–ด์ฃผ๋ฉด ์•Œ์•„์„œ ์ฝ”๋“œ๋ฅผ ์ฐ์–ด๋‚ด๋Š” ํ‹€

#include <iostream>

template <typename T, int num>
T add_num(T t) {
	return t + num;
}

int main() {
	int x = 3;
	std::cout << "x : " << add_num<int, 5>(x) << std::endl;

	return 0;
}
x : 8

ํ…œํ”Œ๋ฆฟ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ํƒ€์ž…๋“ค์€

  • ์ •์ˆ˜ ํƒ€์ž…(bool, char, int, long),
  • ํฌ์ธํ„ฐ ํƒ€์ž…,
  • std::nullptr_t(๋„ ํฌ์ธํ„ฐ)๋กœ ์ œํ•œ๋˜์–ด ์žˆ๋‹ค.

์ถ”๊ฐ€์ ์œผ๋กœ ํ…œํ”Œ๋ฆฟ๋„ ๋””ํดํŠธ ์ธ์ž๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

template<typename T, int num = 5>

์•„๋ž˜์˜ ์˜ˆ์ œ๋Š” ํ…œํ”Œ๋ฆฟ์„ ์ด์šฉํ•˜์—ฌ Vectorํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค. ํฌ๊ฒŒ Functor์™€ Template๋‘๊ฐ€์ง€ ๊ฐœ๋…์ด ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

#include <iostream>

template <typename T>
class Vector {
	
private:
	T* data;
	int capacity;
	int length;

public:
	typedef T value_type;

	Vector(int n = 1) : data(new T[n]), capacity(n), length(0) {}

	void push_back(int s) {
		if (capacity <= length) {
			T* temp = new T[capacity * 2];
			for (int i = 0; i < length; i++) {
				temp[i] = data[i];
			}
			delete[] data;
			data = temp;
			capacity *= 2;
		}
		data[length] = s;
		length++;
	}

	T operator[](int i) {
		return data[i];
	}

	void remove(int x) {
		for (int i = x + 1; i < length; i++) {
			data[i - 1] = data[i];
		}
		length--;
	}

	int size() {
		return length;
	}

	void swap(int i, int j) {
		T temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

	~Vector() {
		if (data) {
			delete[] data;
		}
	}
};

template <typename Cont>
void bubble_sort(Cont& cont) {
	for (int i = 0; i < cont.size(); i++) {
		for (int j = i + 1; j < cont.size(); j++) {
			if (cont[i] > cont[j]) {
				cont.swap(i, j);
			}
		}
	}
}

template <typename Cont, typename Comp>
void bubble_sort(Cont & cont, Comp & comp) {
	for (int i = 0; i < cont.size(); i++) {
		for (int j = i + 1; j < cont.size(); j++) {
			if (!comp(cont[i], cont[j])) {
				cont.swap(i, j);
			}
		}
	}
}

struct Comp1 {
	bool operator()(int a, int b) {
		return a > b;
	}
};

struct Comp2 {
	bool operator()(int a, int b) {
		return a < b;
	}
};

int main() {
	Vector<int> int_vec; // ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ ์ธ์Šคํ„ด์Šคํ™”(class template instantiation)
	int_vec.push_back(3);
	int_vec.push_back(1);
	int_vec.push_back(2);
	int_vec.push_back(8);
	int_vec.push_back(5);
	int_vec.push_back(3);

	std::cout << "์ •๋ ฌ ์ด์ „ ---- " << std::endl;
	for (int i = 0; i < int_vec.size(); i++) {
		std::cout << int_vec[i] << " "; // operator ์ •์˜์— ์˜ํ•ด ์‚ฌ์šฉ๊ฐ€๋Šฅ
	}

	std::cout << std::endl <<  "๊ธฐ์กด ๋ฉ”์„œ๋“œ ์ด์šฉํ•˜์—ฌ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ ---- " << std::endl;
	bubble_sort(int_vec);
	for (int i = 0; i < int_vec.size(); i++) {
		std::cout << int_vec[i] << " "; // operator ์ •์˜์— ์˜ํ•ด ์‚ฌ์šฉ๊ฐ€๋Šฅ
	}

	Comp1 comp1; // ํ•จ์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ํ•จ์ˆ˜์ธ ์ฒ™์„ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ผ๊ณ  ํ•จ(Functor)
	bubble_sort(int_vec, comp1);

	std::cout << std::endl << "๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ ์ดํ›„ ---- " << std::endl;
	for (int i = 0; i < int_vec.size(); i++) {
		std::cout << int_vec[i] << " "; // // operator ์ •์˜์— ์˜ํ•ด ์‚ฌ์šฉ๊ฐ€๋Šฅ
	}
	std::cout << std::endl;

	Comp2 comp2; // ํ•จ์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ ํ•จ์ˆ˜์ธ ์ฒ™์„ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ผ๊ณ  ํ•จ(Functor)
	bubble_sort(int_vec, comp2);

	std::cout << std::endl << "์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ ์ดํ›„ ---- " << std::endl;
	for (int i = 0; i < int_vec.size(); i++) {
		std::cout << int_vec[i] << " ";
	}
	std::cout << std::endl;
}

Typename

  • template <typename T> == template <class T>์€ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ์ค‘์ฒฉ ์˜์กด ํƒ€์ž… ์ด๋ฆ„์„ ์‹๋ณ„ํ•˜๋Š” ์šฉ๋„์—์„œ๋Š” ๋ฐ˜๋“œ์‹œ typename์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. c++ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์–ด๋–ค ํ‚ค์›Œ๋“œ๋Š” typedef๋กœ ์žฌ์ •์˜ ๋œ type์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด typename ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
    ์•„๋ž˜์˜ ์ฝ”๋“œ์—์„œ iterator๊ฐ€ vector์˜ ์˜์กดํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์— iterator๊ฐ€ type์ด๋ผ๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด typename ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
template <typename T>
void print_vector(std::vector<T>& vec) {
  // ์ „์ฒด ๋ฒกํ„ฐ๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ
  for (typename std::vector<T>::iterator itr = vec.begin(); itr != vec.end();
       ++itr) {
    std::cout << *itr << std::endl;
  }
}
int main() {
  std::vector<int> vec;
  vec.push_back(10);
  vec.push_back(20);
  vec.push_back(30);
  vec.push_back(40);

  std::cout << "๋ฒกํ„ฐ ์ƒํƒœ" << std::endl;
  print_vector(vec);
  std::cout << "----------------------------" << std::endl;

	return 0;
}

Using, Typedef

typedef Ratio_add<rat, rat2> rat3;
using rat3 = Ratio_add<rat, rat2>;

์œ„ ๋‘ ๋ฌธ์žฅ ๋ชจ๋‘ ๋™์ผํ•œ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง„๋‹ค. using์„ ์‚ฌ์šฉํ•˜์˜€์„ ๊ฒฝ์šฐ typedef ๋ณด๋‹ค ์ข€ ๋” ์ง๊ด€์ ์ธ ์ดํ•ด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์กด์žฌํ•œ๋‹ค. (C+11๋ถ€ํ„ฐ ์‚ฌ์šฉ๊ฐ€๋Šฅ)

C++ Standard Template Library(STL)

  • ์ž„์˜ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋ณด๊ด€ํ•  ์ˆ˜ ์žˆ๋Š” ์ปจํ…Œ์ด๋„ˆ container
  • ์ปจํ…Œ์ด๋„ˆ์— ๋ณด๊ด€๋œ ์›์†Œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ณต์ž iterator
  • ๋ฐ˜๋ณต์ž๋“ค์„ ๊ฐ€์ง€๊ณ  ์ผ๋ จ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ algorithm

Container

Vector (std::vector)

#include <iostream>
#include <vector>

int main() {
	std::vector<int> vec;

	vec.push_back(10);
	vec.push_back(20);
	vec.push_back(30);
	vec.push_back(40);


	for (std::vector<int>::size_type i = 0; i < vec.size(); i++) {
		std::cout << "vec ์˜" << i + 1 << "๋ฒˆ์งธ ์›์†Œ::" << vec[i] << std::endl;
	}
}

๋ฒกํ„ฐ์˜ ํฌ๊ธฐ๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” size()์˜ ๊ฒฝ์šฐ, ๊ทธ ๋ฆฌํ„ดํ•˜๋Š” ๊ฐ’์˜ ํƒ€์ž…์€ size_type ๋ฉค๋ฒ„ ํƒ€์ž…์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค.

// ํฌ๊ธฐ๊ฐ€ 10์ธ ๋ฒกํ„ฐ ์„ ์–ธ
std::vector<int> vec2(10);
	
// ํฌ๊ธฐ๊ฐ€ 10์ด๊ณ , ๋ชจ๋“  ์›์†Œ๊ฐ€ 3์œผ๋กœ ์ดˆ๊ธฐํ™”๋œ ๋ฒกํ„ฐ ์„ ์–ธ
std::vector<int> vec3(10, 3);

// ์ง€์ •ํ•œ ์ดˆ๊ธฐ๊ฐ’์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ํฌ๊ธฐ๊ฐ€ 5์ธ ๋ฒกํ„ฐ ์„ ์–ธ
std::vector<int> vec4 = { 1,2,3,4,5 };

// ๋ฒกํ„ฐ ๋ฐฐ์—ด ์ƒ์„ฑ(ํ–‰์€ ๊ฐ€๋ณ€์ธ์ง€๋งŒ, ์—ด์€ ๊ณ ์ •)
std::vector<int> vec5[] = { {1,2},{3,4} };
	
// 2์ฐจ์› ๋ฒกํ„ฐ ์ƒ์„ฑ(ํ–‰๊ณผ ์—ด ๋ชจ๋‘ ๊ฐ€๋ณ€)
std::vector<std::vector<int>> vec6;

image

Deque (std::deque)

#include <iostream>
#include <deque>

template <typename T>
void print_deque(std::deque<T>& dq) {
	std::cout << "[ ";
	for (const auto& elem : dq) {
		std::cout << elem << " ";
	}
	std::cout << "] " << std::endl;
}

int main() {
	std::deque<int> dq;

	dq.push_back(10);
	dq.push_back(20);
	dq.push_back(30);
	dq.push_back(40);

	std::cout << "์ดˆ๊ธฐ dq ์ƒํƒœ" << std::endl;
	print_deque(dq);

	std::cout << "๋งจ ์•ž์˜ ์›์†Œ ์ œ๊ฑฐ" << std::endl;
	dq.pop_front();
	print_deque(dq);
}

์ถ”๊ฐ€์ ์œผ๋กœ ์–‘๋ฐฉํ–ฅ ํ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋“ค ์‚ฌ์šฉ๊ฐ€๋Šฅ

  • dequeue.push_front(10)
  • dequeue.push_back(50)
  • dequeue.pop_front()
  • dequeue.pop_back()

Set (std::set)

#include <iostream>
#include <set>

template<typename T>
void print_set(std::set<T>& s) {
	std::cout << "[ ";

	for (typename std::set<T>::iterator itr = s.begin(); itr != s.end(); itr++) {
		std::cout << *itr << " ";
	}
	std::cout << " ] " << std::endl;
}

int main() {
	std::set<int> s;
	s.insert(10);
	s.insert(50);
	s.insert(20);
	s.insert(40);
	s.insert(30);

	std::cout << "์ˆœ์„œ๋Œ€๋กœ ์ •๋ ฌ๋˜์„œ ๋‚˜์˜จ๋‹ค" << std::endl;
	print_set(s);

	std::cout << "20์ด s์˜ ์›์†Œ์ธ๊ฐ€์š”? :: ";
	auto itr = s.find(20);
	if (itr != s.end()) {
		std::cout << "Yes" << std::endl;
	}

	else {
		std::cout << "No" << std::endl;
	}

	std::cout << "25๊ฐ€ s์˜ ์›์†Œ์ธ๊ฐ€์š”? :: ";
	itr = s.find(25);
	if (itr != s.end()) {
		std::cout << "Yes" << std::endl;
	}

	else {
		std::cout << "No" << std::endl;
	}
}

image

๋‚ด๋ถ€์ ์œผ๋กœ ์™„์ „ ์ด์ง„ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š” set, ๊ฐ๊ฐ์˜ ์›์†Œ๋“ค์€ ํŠธ๋ฆฌ์˜ ๊ฐ ๋…ธ๋“œ๋“ค์— ์ €์žฅ๋˜์–ด ์žˆ๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ทœ์น™์„ ์ง€ํ‚ค๋ฉฐ set์•ˆ์—๋Š” ์ค‘๋ณต๋œ ์›์†Œ๋“ค์ด ์—†๋‹ค.

  • ์™ผ์ชฝ์— ์˜ค๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋“ค์€ ๋‚˜๋ณด๋‹ค ์ž‘๋‹ค.
  • ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋“ค์€ ๋‚˜๋ณด๋‹ค ํฌ๋‹ค.

s.find(20)์„ ํ†ตํ•ด ์›์†Œ์˜ ์กด์žฌ ์œ ๋ฌด๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹คํ–‰์‹œ๊ฐ„์€ O(log(N)), ๋งŒ์•ฝ ์›์†Œ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด s.end()๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

Map (std::map)

#include <iostream>
#include <map>
#include <string>

template <typename K, typename V>
void print_map(std::map<K, V>& m) {
	for (auto itr = m.begin(); itr != m.end(); itr++) {
		std::cout << itr->first << " " << itr->second << std::endl;
	}
}

template <typename K, typename V>
void search_and_print(std::map<K, V>& m, K key) {
	auto itr = m.find(key);
	if (itr != m.end()) {
		std::cout << key << " ---> " << itr->second << std::endl;
	}

	else {
		std::cout << key << "์€(๋Š”) ๋ชฉ๋ก์— ์—†์Šต๋‹ˆ๋‹ค." << std::endl;
	}
}

int main() {
	std::map<std::string, double> pitcher_list;

	pitcher_list.insert(std::make_pair("์ฐจ์šฐ์ฐฌ", 3.04));
	pitcher_list.insert(std::make_pair("์žฅ์›์ค€", 3.05));
	pitcher_list.insert(std::make_pair("ํ—ฅํ„ฐ", 3.09));

	pitcher_list["๋‹ˆํผํŠธ"] = 3.56;
	pitcher_list["๋ฐ•์ข…ํ›ˆ"] = 3.76;
	pitcher_list["์ผˆ๋ฆฌ"] = 3.90;

	print_map(pitcher_list);
	std::cout << "------------------------------" << std::endl;

	// [] ์—ฐ์‚ฐ์ž๋Š”, ๋งต์— ์—†๋Š” ํ‚ค๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋ฉด, ์ž๋™์œผ๋กœ ๊ฐ’์˜ ๋””ํดํŠธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ฒ„๋ฆฐ๋‹ค.
	// ์›์†Œ์— ๋Œ€์‘๋˜๋Š” ๊ฐ’์„ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด insert๊ฐ€ ์•„๋‹Œ []์—ฐ์‚ฐ์ž๋ฅผ ํ™œ์šฉํ•œ๋‹ค.
	std::cout << "๋ฐ•์„ธ์›… ๋ฐฉ์–ด์œจ์€? :: " << pitcher_list["๋ฐ•์„ธ์›…"] << std::endl;

	search_and_print(pitcher_list, std::string("์˜ค์Šนํ™˜"));
	search_and_print(pitcher_list, std::string("๋ฅ˜ํ˜„์ง„"));
}

[]์—ฐ์‚ฐ์ž๋Š” ๋งต์— ์—†๋Š” ํ‚ค๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋ฉด, ์ž๋™์œผ๋กœ ๊ฐ’์˜ ๋””ํดํŠธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์›์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ด๋ฒ„๋ฆฐ๋‹ค.
map์—ญ์‹œ set์ฒ˜๋Ÿผ ์ค‘๋ณต๋œ ์›์†Œ๋ฅผ ํ—ˆ๋ฝํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋ฏธ, ๊ฐ™์€ ํ‚ค๊ฐ€ ์›์†Œ๋กœ ๋“ค์–ด์žˆ๋‹ค๋ฉด ๋‚˜์ค‘์— ์˜ค๋Š” insert๋Š” ๋ฌด์‹œ๋œ๋‹ค.
์›์†Œ์— ๋Œ€์‘๋˜๋Š” ๊ฐ’์„ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด insert๊ฐ€ ์•„๋‹Œ []์—ฐ์‚ฐ์ž๋กœ ๋Œ€์‘๋˜๋Š” ๊ฐ’์„ ๋ฐ”๊ฟ”์ค„ ์ˆ˜ ์žˆ๋‹ค.

# Value๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ, map์„ vector๋กœ ์˜ฎ๊ฒจ์ค˜์•ผํ•จ
# comp ํ•จ์ˆ˜๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ์€ < , ๋‚ด๋ฆผ์ฐจ์ˆœ์€ > ํ˜•ํƒœ์ด๋‹ค. ๋‹ค๋ฅธ ๋ธ”๋กœ๊ทธ์—์„œ ๋ณด์•˜๋Š”๋ฐ < ๋ชจ์–‘์ด ํฌ๋ ˆ์„ผ๋„์™€ ๋‹ฎ์•˜์œผ๋‹ˆ ๋’ค๋กœ ๊ฐˆ์ˆ˜๋ก ํฐ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์™ธ์šฐ๊ธฐ ์‰ฝ๋‹ค.
map<char, int> m;
vector<pair<char,  int>> v(m.begin(), m.end());

sort(v.begin(), v.end(), comp);

๊ฒฐ๋ก 

  • ๋ฐ์ดํ„ฐ์˜ ์กด์žฌ ์œ ๋ฌด๋งŒ ๊ถ๊ธˆํ•œ ๊ฒฝ์šฐ $\rightarrow$ set
  • ์ค‘๋ณต ๋ฐ์ดํ„ฐ๋ฅผ ํ—ˆ๋ฝํ•  ๊ฒฝ์šฐ $\rightarrow$ multiset
  • ๋ฐ์ดํ„ฐ์— ๋Œ€์‘๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ $\rightarrow$ map
  • ์ค‘๋ณต ํ‚ค๋ฅผ ํ—ˆ๋ฝํ•  ๊ฒฝ์šฐ $\rightarrow$ multimap

Iterator

#include <iostream>
#include <vector>

template<typename T>
void print_vector(std::vector<T>& vec) {
	std::cout << "[ ";

	for (typename std::vector<T>::iterator itr = vec.begin(); itr != vec.end(); ++itr) {
		std::cout << *itr << " ";
	}
	
	std::cout << "]" << std::endl;
}

template<typename T>
void print_reverse_vector(std::vector<T>& vec) {
	std::cout << "[ ";

	for (typename std::vector<T>::reverse_iterator itr = vec.rbegin(); itr != vec.rend(); ++itr) {
		std::cout << *itr << " ";
	}

	std::cout << "]" << std::endl;
}

template<typename T>
void print_range_vector(std::vector<T>& vec) {
	std::cout << "[ ";

	for (const auto &i: vec) {
		std::cout << i << " ";
	}

	std::cout << "]" << std::endl;
}


int main() {
	std::vector<int> vec;

	vec.push_back(10);
	vec.push_back(20);
	vec.push_back(30);
	vec.push_back(40);
	vec.push_back(20);

	print_vector(vec);
	print_reverse_vector(vec);
	print_range_vector(vec);
}
  • std::vector<T>::iterator itr = vec.begin()์€ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐ˜๋ณต์ž๋ฅผ ๋ฆฌํ„ด
  • std::vector<T>::iterator itr = vec.end()๋Š” ๋งˆ์ง€๋ง‰ ์›์†Œ ํ•œ ์นธ ๋’ค๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐ˜๋ณต์ž๋ฅผ ๋ฆฌํ„ด
  • std::vector<T>::reverse_iterator itr = vec.rbegin()์€ ๋งˆ์ง€๋ง‰ ์›์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐ˜๋ณต์ž๋ฅผ ๋ฆฌํ„ด
  • std::vector<T>::reverse_iterator itr = vec.rend()์€ ์ฒซ๋ฒˆ์งธ ์›์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐ˜๋ณต์ž๋ฅผ ๋ฆฌํ„ด

Smart Pointer

new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๋™์ ์œผ๋กœ ํ• ๋‹น๋ฐ›์€ ๋ฉ”๋ชจ๋ฆฌ๋Š”, ๋ฐ˜๋“œ์‹œ delete ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์ œํ•ด์•ผํ•จ. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(memory leak)๋กœ๋ถ€ํ„ฐ ํ”„๋กœ๊ทธ๋žจ์˜ ์•ˆ์ •์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ•˜์˜€๋‹ค. ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋ž€ ํฌ์ธํ„ฐ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ํด๋ž˜์Šค ํ…œํ”Œ๋ฆฟ์œผ๋กœ, ์‚ฌ์šฉ์ด ๋๋‚œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ œํ•ด ์ค€๋‹ค.

๋ณดํ†ต new ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ๊ธฐ๋ณธ ํฌ์ธํ„ฐ(raw pointer)๊ฐ€ ์‹ค์ œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ์ดˆ๊ธฐํ™”ํ•œ ํ›„์—, ๊ธฐ๋ณธ ํฌ์ธํ„ฐ๋ฅผ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์— ๋Œ€์ž…ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ •์˜๋œ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ ์ˆ˜๋ช…์ด ๋‹คํ•˜๋ฉด, ์†Œ๋ฉธ์ž๋Š” delete ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ œํ•œ๋‹ค. ๋”ฐ๋ผ์„œ new ํ‚ค์›Œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฃผ์†Œ๊ฐ’์„ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์— ๋Œ€์ž…ํ•˜๋ฉด, ๋”ฐ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค.

unique_ptr

unique_ptr์€ ํ•˜๋‚˜์˜ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋งŒ์ด ํŠน์ • ๊ฐ์ฒด๋ฅผ ์†Œ์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก, ๊ฐ์ฒด์— ์†Œ์œ ๊ถŒ ๊ฐœ๋…์„ ๋„์ž…ํ•œ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์ด๋‹ค.

unique_ptr<int> ptr01(new int(5)); // intํ˜• unique_ptr์ธ ptr01์„ ์„ ์–ธํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•จ.

auto ptr02 = move(ptr01);          // ptr01์—์„œ ptr02๋กœ ์†Œ์œ ๊ถŒ์„ ์ด์ „ํ•จ.

// unique_ptr<int> ptr03 = ptr01;  // ๋Œ€์ž… ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•œ ๋ณต์‚ฌ๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด. 

ptr02.reset();                     // ptr02๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์‚ญ์ œํ•จ.

ptr01.reset();                     // ptr01๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ์‚ญ์ œํ•จ.

Person ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” hong์ด๋ผ๋Š” unique_ptr๋ฅผ make_unique() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค.

#include <iostream>
#include <memory>
using namespace std;

class Person {

private:
    string name_;
    int age_;

public:
    Person(const string& name, int age); // ๊ธฐ์ดˆ ํด๋ž˜์Šค ์ƒ์„ฑ์ž์˜ ์„ ์–ธ
    ~Person() { cout << "์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." << endl; }
    void ShowPersonInfo();
};

int main(void) {
    unique_ptr<Person> hong = make_unique<Person>("๊ธธ๋™", 29);
    hong->ShowPersonInfo();
    return 0;
}
 
Person::Person(const string& name, int age) {
    name_ = name;
    age_ = age;
    cout << "์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." << endl;
}

void Person::ShowPersonInfo() { cout << name_ << "์˜ ๋‚˜์ด๋Š” " << age_ << "์‚ด์ž…๋‹ˆ๋‹ค." << endl; }
์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
๊ธธ๋™์˜ ๋‚˜์ด๋Š” 29์‚ด์ž…๋‹ˆ๋‹ค.
์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

shared_ptr

shared_ptr์€ ํ•˜๋‚˜์˜ ํŠน์ • ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๊ฐ€ ์ด ๋ช‡ ๊ฐœ์ธ์ง€๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์ด๋‹ค.
์ด๋ ‡๊ฒŒ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ ๊ฐœ์ˆ˜๋ฅผ ์ฐธ์กฐ ํšŸ์ˆ˜(reference count)๋ผ๊ณ  ํ•œ๋‹ค.
์ฐธ์กฐ ํšŸ์ˆ˜๋Š” ํŠน์ • ๊ฐ์ฒด์— ์ƒˆ๋กœ์šด shared_ptr์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค 1์”ฉ ์ฆ๊ฐ€ํ•˜๋ฉฐ, ์ˆ˜๋ช…์ด ๋‹คํ•  ๋•Œ๋งˆ๋‹ค 1์”ฉ ๊ฐ์†Œํ•œ๋‹ค.
๋”ฐ๋ผ์„œ ๋งˆ์ง€๋ง‰ shared_ptr์˜ ์ˆ˜๋ช…์ด ๋‹คํ•˜์—ฌ, ์ฐธ์กฐ ํšŸ์ˆ˜๊ฐ€ 0์ด ๋˜๋ฉด delete ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ œํ•œ๋‹ค.

shared_ptr<int> ptr01(new int(5)); // intํ˜• shared_ptr์ธ ptr01์„ ์„ ์–ธํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•จ.

cout << ptr01.use_count() << endl; // 1

auto ptr02(ptr01);                 // ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•œ ์ดˆ๊ธฐํ™”

cout << ptr01.use_count() << endl; // 2

auto ptr03 = ptr01;                // ๋Œ€์ž…์„ ํ†ตํ•œ ์ดˆ๊ธฐํ™”

cout << ptr01.use_count() << endl; // 3  

Person ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” hong์ด๋ผ๋Š” shared_ptr๋ฅผ make_shared() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒ์„ฑํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค.

shared_ptr<Person> hong = make_shared<Person>("๊ธธ๋™", 29);

cout << "ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : " << hong.use_count() << endl; // 1

auto han = hong;

cout << "ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : " << hong.use_count() << endl; // 2

han.reset(); // shared_ptr์ธ han์„ ํ•ด์ œํ•จ.

cout << "ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : " << hong.use_count() << endl; // 1
์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : 1
ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : 2
ํ˜„์žฌ ์†Œ์œ ์ž ์ˆ˜ : 1
์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Eigen

Multiplication

  Eigen::Matrix3d A = Eigen::Matrix3d::Identity();
  Eigen::Vector3d a(0.5, 3, -0.4);
  Eigen::Vector3d Aa = A * a;
  std::cout << "The multiplication of A * a is " << std::endl << Aa << std::endl; // Result of Aa: 0.5 3 -0.4

  Eigen::MatrixXd B = Eigen::MatrixXd::Identity(6, 5);
  Eigen::VectorXd b(5);
  b << 1, 4, 6, -2, 0.4;
  Eigen::VectorXd Bb = B * b;
  std::cout << "The multiplication of B * b is " << std::endl << Bb << std::endl; // Result of Bb: 1, 4, 6, -2, 0.4;

Transpose and inverse

Eigen::MatrixXd A(3, 2);
A << 1, 2,
     2, 3,
     3, 4;

Eigen::MatrixXd B = A.transpose();// the transpose of A is a 2x3 matrix
Eigen::MatrixXd C = (B * A).inverse();// computer the inverse of BA, which is a 2x2 matrix

Dot product and cross product

Eigen::Vector3d v(1, 2, 3);
Eigen::Vector3d w(0, 1, 2);

double vDotw = v.dot(w); // dot product of two vectors(๋‚ด์ )
Eigen::Vector3d vCrossw = v.cross(w); // cross product of two vectors(์™ธ์ )

Accessing matrix

Eigen::MatrixXd A = Eigen::MatrixXd::Random(7, 9);
std::cout << "The element at fourth row and 7the column is " << A(3, 6) << std::endl;

Eigen::MatrixXd B = A.block(1, 2, 3, 3); // block(start rows, startcols, num_rows, num_cols)
std::cout << "Take sub-matrix whose upper left corner is A(1, 2)" << std::endl << B << std::endl;

Eigen::VectorXd a = A.col(1); // take the second column of A
Eigen::VectorXd b = B.row(0); // take the first row of B

Eigen::VectorXd c = a.head(3);// take the first three elements of a
Eigen::VectorXd d = b.tail(2);// take the last two elements of b

Quaternion

Eigen::Quaterniond q(2, 0, 1, -3); 
std::cout << "This quaternion consists of a scalar " << q.w() << " and a vector " << std::endl << q.vec() << std::endl;

q.normalize();
std::cout << "To represent rotation, we need to normalize it such that its length is " << q.norm() << std::endl;

Eigen::Vector3d v(1, 2, -1);
Eigen::Quaterniond p;

p.w() = 0;
p.vec() = v;

Eigen::Quaterniond rotatedP = q * p * q.inverse(); 
Eigen::Vector3d rotatedV = rotatedP.vec();
std::cout << "We can now use it to rotate a vector " << std::endl << v << " to " << std::endl << rotatedV << std::endl;

Eigen::Matrix3d R = q.toRotationMatrix(); // convert a quaternion to a 3x3 rotation matrix
std::cout << "Compare with the result using an rotation matrix " << std::endl << R * v << std::endl;

Eigen::Quaterniond a = Eigen::Quterniond::Identity();
Eigen::Quaterniond b = Eigen::Quterniond::Identity();

Eigen::Quaterniond c; // Adding two quaternion as two 4x1 vectors is not supported by the EIgen API. That is, c = a + b is not allowed. We have to do this in a hard way

c.w() = a.w() + b.w();
c.x() = a.x() + b.x();
c.y() = a.y() + b.y();
c.z() = a.z() + b.z();

Basic Usage

#include <Eigen/Dense>

Matrix<double, 3, 3> A;               // Fixed rows and cols. Same as Matrix3d.
Matrix<double, 3, Dynamic> B;         // Fixed rows, dynamic cols.
Matrix<double, Dynamic, Dynamic> C;   // Full dynamic. Same as MatrixXd.
Matrix<double, 3, 3, RowMajor> E;     // Row major; default is column-major.
Matrix3f P, Q, R;                     // 3x3 float matrix.
Vector3f x, y, z;                     // 3x1 float matrix.
RowVector3f a, b, c;                  // 1x3 float matrix.
VectorXd v;                           // Dynamic column vector of doubles
double s;                            

// Basic usage
// Eigen          // Matlab           // comments
x.size()          // length(x)        // vector size
C.rows()          // size(C,1)        // number of rows
C.cols()          // size(C,2)        // number of columns
x(i)              // x(i+1)           // Matlab is 1-based
C(i,j)            // C(i+1,j+1)       //

A.resize(4, 4);   // Runtime error if assertions are on.
B.resize(4, 9);   // Runtime error if assertions are on.
A.resize(3, 3);   // Ok; size didn't change.
B.resize(3, 9);   // Ok; only dynamic cols changed.
                  
A << 1, 2, 3,     // Initialize A. The elements can also be
     4, 5, 6,     // matrices, which are stacked along cols
     7, 8, 9;     // and then the rows are stacked.
B << A, A, A;     // B is three horizontally stacked A's.
A.fill(10);       // Fill A with all 10's.

// Eigen                                    // Matlab
MatrixXd::Identity(rows,cols)               // eye(rows,cols)
C.setIdentity(rows,cols)                    // C = eye(rows,cols)
MatrixXd::Zero(rows,cols)                   // zeros(rows,cols)
C.setZero(rows,cols)                        // C = zeros(rows,cols)
MatrixXd::Ones(rows,cols)                   // ones(rows,cols)
C.setOnes(rows,cols)                        // C = ones(rows,cols)
MatrixXd::Random(rows,cols)                 // rand(rows,cols)*2-1            // MatrixXd::Random returns uniform random numbers in (-1, 1).
C.setRandom(rows,cols)                      // C = rand(rows,cols)*2-1
VectorXd::LinSpaced(size,low,high)          // linspace(low,high,size)'
v.setLinSpaced(size,low,high)               // v = linspace(low,high,size)'
VectorXi::LinSpaced(((hi-low)/step)+1,      // low:step:hi
                    low,low+step*(size-1))  //


// Matrix slicing and blocks. All expressions listed here are read/write.
// Templated size versions are faster. Note that Matlab is 1-based (a size N
// vector is x(1)...x(N)).
// Eigen                           // Matlab
x.head(n)                          // x(1:n)
x.head<n>()                        // x(1:n)
x.tail(n)                          // x(end - n + 1: end)
x.tail<n>()                        // x(end - n + 1: end)
x.segment(i, n)                    // x(i+1 : i+n)
x.segment<n>(i)                    // x(i+1 : i+n)
P.block(i, j, rows, cols)          // P(i+1 : i+rows, j+1 : j+cols)
P.block<rows, cols>(i, j)          // P(i+1 : i+rows, j+1 : j+cols)
P.row(i)                           // P(i+1, :)
P.col(j)                           // P(:, j+1)
P.leftCols<cols>()                 // P(:, 1:cols)
P.leftCols(cols)                   // P(:, 1:cols)
P.middleCols<cols>(j)              // P(:, j+1:j+cols)
P.middleCols(j, cols)              // P(:, j+1:j+cols)
P.rightCols<cols>()                // P(:, end-cols+1:end)
P.rightCols(cols)                  // P(:, end-cols+1:end)
P.topRows<rows>()                  // P(1:rows, :)
P.topRows(rows)                    // P(1:rows, :)
P.middleRows<rows>(i)              // P(i+1:i+rows, :)
P.middleRows(i, rows)              // P(i+1:i+rows, :)
P.bottomRows<rows>()               // P(end-rows+1:end, :)
P.bottomRows(rows)                 // P(end-rows+1:end, :)
P.topLeftCorner(rows, cols)        // P(1:rows, 1:cols)
P.topRightCorner(rows, cols)       // P(1:rows, end-cols+1:end)
P.bottomLeftCorner(rows, cols)     // P(end-rows+1:end, 1:cols)
P.bottomRightCorner(rows, cols)    // P(end-rows+1:end, end-cols+1:end)
P.topLeftCorner<rows,cols>()       // P(1:rows, 1:cols)
P.topRightCorner<rows,cols>()      // P(1:rows, end-cols+1:end)
P.bottomLeftCorner<rows,cols>()    // P(end-rows+1:end, 1:cols)
P.bottomRightCorner<rows,cols>()   // P(end-rows+1:end, end-cols+1:end)

// Of particular note is Eigen's swap function which is highly optimized.
// Eigen                           // Matlab
R.row(i) = P.col(j);               // R(i, :) = P(:, j)
R.col(j1).swap(mat1.col(j2));      // R(:, [j1 j2]) = R(:, [j2, j1])

// Views, transpose, etc;
// Eigen                           // Matlab
R.adjoint()                        // R'
R.transpose()                      // R.' or conj(R')       // Read-write
R.diagonal()                       // diag(R)               // Read-write
x.asDiagonal()                     // diag(x)
R.transpose().colwise().reverse()  // rot90(R)              // Read-write
R.rowwise().reverse()              // fliplr(R)
R.colwise().reverse()              // flipud(R)
R.replicate(i,j)                   // repmat(P,i,j)


// All the same as Matlab, but matlab doesn't have *= style operators.
// Matrix-vector.  Matrix-matrix.   Matrix-scalar.
y  = M*x;          R  = P*Q;        R  = P*s;
a  = b*M;          R  = P - Q;      R  = s*P;
a *= M;            R  = P + Q;      R  = P/s;
                   R *= Q;          R  = s*P;
                   R += Q;          R *= s;
                   R -= Q;          R /= s;

// Vectorized operations on each element independently
// Eigen                       // Matlab
R = P.cwiseProduct(Q);         // R = P .* Q
R = P.array() * s.array();     // R = P .* s
R = P.cwiseQuotient(Q);        // R = P ./ Q
R = P.array() / Q.array();     // R = P ./ Q
R = P.array() + s.array();     // R = P + s
R = P.array() - s.array();     // R = P - s
R.array() += s;                // R = R + s
R.array() -= s;                // R = R - s
R.array() < Q.array();         // R < Q
R.array() <= Q.array();        // R <= Q
R.cwiseInverse();              // 1 ./ P
R.array().inverse();           // 1 ./ P
R.array().sin()                // sin(P)
R.array().cos()                // cos(P)
R.array().pow(s)               // P .^ s
R.array().square()             // P .^ 2
R.array().cube()               // P .^ 3
R.cwiseSqrt()                  // sqrt(P)
R.array().sqrt()               // sqrt(P)
R.array().exp()                // exp(P)
R.array().log()                // log(P)
R.cwiseMax(P)                  // max(R, P)
R.array().max(P.array())       // max(R, P)
R.cwiseMin(P)                  // min(R, P)
R.array().min(P.array())       // min(R, P)
R.cwiseAbs()                   // abs(P)
R.array().abs()                // abs(P)
R.cwiseAbs2()                  // abs(P.^2)
R.array().abs2()               // abs(P.^2)
(R.array() < s).select(P,Q );  // (R < s ? P : Q)
R = (Q.array()==0).select(P,A) // R(Q==0) = P(Q==0)
R = P.unaryExpr(ptr_fun(func)) // R = arrayfun(func, P)   // with: scalar func(const scalar &x);


// Reductions.
int r, c;
// Eigen                  // Matlab
R.minCoeff()              // min(R(:))
R.maxCoeff()              // max(R(:))
s = R.minCoeff(&r, &c)    // [s, i] = min(R(:)); [r, c] = ind2sub(size(R), i);
s = R.maxCoeff(&r, &c)    // [s, i] = max(R(:)); [r, c] = ind2sub(size(R), i);
R.sum()                   // sum(R(:))
R.colwise().sum()         // sum(R)
R.rowwise().sum()         // sum(R, 2) or sum(R')'
R.prod()                  // prod(R(:))
R.colwise().prod()        // prod(R)
R.rowwise().prod()        // prod(R, 2) or prod(R')'
R.trace()                 // trace(R)
R.all()                   // all(R(:))
R.colwise().all()         // all(R)
R.rowwise().all()         // all(R, 2)
R.any()                   // any(R(:))
R.colwise().any()         // any(R)
R.rowwise().any()         // any(R, 2)

// Dot products, norms, etc.
// Eigen                  // Matlab
x.norm()                  // norm(x).    Note that norm(R) doesn't work in Eigen.
x.squaredNorm()           // dot(x, x)   Note the equivalence is not true for complex
x.dot(y)                  // dot(x, y)
x.cross(y)                // cross(x, y) Requires #include <Eigen/Geometry>

//// Type conversion
// Eigen                  // Matlab
A.cast<double>();         // double(A)
A.cast<float>();          // single(A)
A.cast<int>();            // int32(A)
A.real();                 // real(A)
A.imag();                 // imag(A)
// if the original type equals destination type, no work is done

// Note that for most operations Eigen requires all operands to have the same type:
MatrixXf F = MatrixXf::Zero(3,3);
A += F;                // illegal in Eigen. In Matlab A = A+F is allowed
A += F.cast<double>(); // F converted to double and then added (generally, conversion happens on-the-fly)

// Eigen can map existing memory into Eigen matrices.
float array[3];
Vector3f::Map(array).fill(10);            // create a temporary Map over array and sets entries to 10
int data[4] = {1, 2, 3, 4};
Matrix2i mat2x2(data);                    // copies data into mat2x2
Matrix2i::Map(data) = 2*mat2x2;           // overwrite elements of data with 2*mat2x2
MatrixXi::Map(data, 2, 2) += mat2x2;      // adds mat2x2 to elements of data (alternative syntax if size is not know at compile time)

// Solve Ax = b. Result stored in x. Matlab: x = A \ b.
x = A.ldlt().solve(b));  // A sym. p.s.d.    #include <Eigen/Cholesky>
x = A.llt() .solve(b));  // A sym. p.d.      #include <Eigen/Cholesky>
x = A.lu()  .solve(b));  // Stable and fast. #include <Eigen/LU>
x = A.qr()  .solve(b));  // No pivoting.     #include <Eigen/QR>
x = A.svd() .solve(b));  // Stable, slowest. #include <Eigen/SVD>
// .ldlt() -> .matrixL() and .matrixD()
// .llt()  -> .matrixL()
// .lu()   -> .matrixL() and .matrixU()
// .qr()   -> .matrixQ() and .matrixR()
// .svd()  -> .matrixU(), .singularValues(), and .matrixV()

// Eigenvalue problems
// Eigen                          // Matlab
A.eigenvalues();                  // eig(A);
EigenSolver<Matrix3d> eig(A);     // [vec val] = eig(A)
eig.eigenvalues();                // diag(val)
eig.eigenvectors();               // vec
// For self-adjoint matrices use SelfAdjointEigenSolver<>
โš ๏ธ **GitHub.com Fallback** โš ๏ธ