CPP - soup1997/Study-Alone GitHub Wiki
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์ ํจ์์ด๋ค๋ผ๊ณ ๋ช
์ํด์ฃผ๋ ๊ฒ์ด ์ข์
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
๋ฅผ ๊ณ์ ์ฐธ์กฐํ๋ค.
๋ ํผ๋ฐ์ค๋ฅผ ๋ฆฌํดํ๊ฒ ๋๋ค๋ฉด ๋ ํผ๋ฐ์ค๊ฐ ์ฐธ์กฐํ๋ ํ์
์ ํฌ๊ธฐ์ ์๊ด์์ด ๋ฑ ํ๋ฒ์ ์ฃผ์๊ฐ ๋ณต์ฌ๋ก ์ ๋ฌ์ด ๋๋๊ฒ ๋๋ค.
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;
}
#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 ๋ฉค๋ฒ ๋ณ์์ ๊ฒฝ์ฐ, ํด๋์ค์ ๋ชจ๋ ๊ฐ์ฒด๋ค์ด '๊ณต์ 'ํ๋ ๋ณ์๋ก์จ ๋ค๋ก ์กด์ฌํ๋ ๋ฉค๋ฒ ๋ณ์๋ค๊ณผ๋ ๋ฌ๋ฆฌ ๋ชจ๋ ๊ฐ์ฒด๋ค์ด 'ํ๋์' static๋ฉค๋ฒ ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.
๋ชจ๋ ์ ์ญ ๋ฐ static ๋ณ์๋ค์ ์ ์์ ๋์์ ๊ฐ์ด ์๋์ผ๋ก 0์ผ๋ก ์ด๊ธฐํ ๋๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๊ตณ์ด ์ด๊ธฐํ ํ์ง ์์๋ ๋๋ค.
๋ํ ๋ฉค๋ฒ ๋ณ์๋ค์ ํด๋์ค ๋ด๋ถ์์ ์ด๊ธฐํํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์๋์ ๊ฐ์ด ์ด๊ธฐํํ๋ค.
int Marine::total_marin_num = 0;
static ํจ์๋ ์ด๋ค ๊ฐ์ฒด์ ์ข ์๋๋ ๊ฒ์ด ์๋๋ผ ํด๋์ค์ ์ข ์๋๋ ๊ฒ์ผ๋ก, ์ด๋ฅผ ํธ์ถํ๋ ๋ฐฉ๋ฒ๋ (๊ฐ์ฒด).(๋ฉค๋ฒ ํจ์)๊ฐ ์๋๋ผ ์๋์ ๊ฐ์ด ํธ์ถํ๋ค.
Marine::show_total_marine();
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(์ฐ์ฐ์) (์ฐ์ฐ์๊ฐ ๋ฐ๋ ์ธ์)
class Mystring {
private:
char* string_content;
int string_length;
public:
bool operator==(Mystring &str);
}
bool Mystring::operator==(Mystring &str) {
return !compare(str);
}
char& Mystring::operator[](const int index) {
return string_content[index];
}
์ปดํ์ผ๋ฌ์์ ์๋์ผ๋ก ์บ์คํ
ํด์ฃผ๋ ์์์ (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 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
ํค์๋๋ฅผ ํตํด์ ๋ช ์์ ์ผ๋ก ๋ํ๋ผ ์ ์์
#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๋ก ๋ง๋ค์ด์ฃผ์ด์ผ ๋์ค์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ฌ์ง๊ฐ ์๊ฒ ๋๋ค.
class A {
public:
int a;
};
class B {
public:
int b;
};
class C: public A, public B {
public:
int c;
};
A -> B -> C
์ ์์๋ก ์์ฑ์๊ฐ ํธ์ถ๋๋ค.
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"
์ฌ์ฉ์๊ฐ ์ํ๋ ํ์ ์ ๋ฃ์ด์ฃผ๋ฉด ์์์ ์ฝ๋๋ฅผ ์ฐ์ด๋ด๋ ํ
#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;
}
-
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;
}
typedef Ratio_add<rat, rat2> rat3;
using rat3 = Ratio_add<rat, rat2>;
์ ๋ ๋ฌธ์ฅ ๋ชจ๋ ๋์ผํ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ค. using์ ์ฌ์ฉํ์์ ๊ฒฝ์ฐ typedef ๋ณด๋ค ์ข ๋ ์ง๊ด์ ์ธ ์ดํด๋ฅผ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์กด์ฌํ๋ค. (C+11๋ถํฐ ์ฌ์ฉ๊ฐ๋ฅ)
- ์์ ํ์
์ ๊ฐ์ฒด๋ฅผ ๋ณด๊ดํ ์ ์๋ ์ปจํ
์ด๋
container
- ์ปจํ
์ด๋์ ๋ณด๊ด๋ ์์์ ์ ๊ทผํ ์ ์๋ ๋ฐ๋ณต์
iterator
- ๋ฐ๋ณต์๋ค์ ๊ฐ์ง๊ณ ์ผ๋ จ์ ์์
์ ์ํํ๋ ์๊ณ ๋ฆฌ์ฆ
algorithm
#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;
#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()
#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;
}
}
๋ด๋ถ์ ์ผ๋ก ์์ ์ด์ง ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋์ด ์๋ set, ๊ฐ๊ฐ์ ์์๋ค์ ํธ๋ฆฌ์ ๊ฐ ๋ ธ๋๋ค์ ์ ์ฅ๋์ด ์๊ณ , ๋ค์๊ณผ ๊ฐ์ ๊ท์น์ ์งํค๋ฉฐ set์์๋ ์ค๋ณต๋ ์์๋ค์ด ์๋ค.
- ์ผ์ชฝ์ ์ค๋ ๋ชจ๋ ๋ ธ๋๋ค์ ๋๋ณด๋ค ์๋ค.
- ์ค๋ฅธ์ชฝ์ ์๋ ๋ชจ๋ ๋ ธ๋๋ค์ ๋๋ณด๋ค ํฌ๋ค.
s.find(20)
์ ํตํด ์์์ ์กด์ฌ ์ ๋ฌด๋ฅผ ํ์
ํ ์ ์๋ค. ์คํ์๊ฐ์ O(log(N))
, ๋ง์ฝ ์์๊ฐ ์กด์ฌํ์ง ์๋๋ค๋ฉด s.end()
๋ฅผ ๋ฆฌํดํ๋ค.
#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
#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()
์ ์ฒซ๋ฒ์งธ ์์๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ฐ๋ณต์๋ฅผ ๋ฆฌํด
new ํค์๋๋ฅผ ์ฌ์ฉํด ๋์ ์ผ๋ก ํ ๋น๋ฐ์ ๋ฉ๋ชจ๋ฆฌ๋, ๋ฐ๋์ delete ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ํด์ ํด์ผํจ. ๋ฉ๋ชจ๋ฆฌ ๋์(memory leak)๋ก๋ถํฐ ํ๋ก๊ทธ๋จ์ ์์ ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ์ค๋งํธ ํฌ์ธํฐ๋ผ๋ ๊ฐ๋ ์ ๋์ ํ์๋ค. ์ค๋งํธ ํฌ์ธํฐ๋ ํฌ์ธํฐ์ฒ๋ผ ๋์ํ๋ ํด๋์ค ํ ํ๋ฆฟ์ผ๋ก, ์ฌ์ฉ์ด ๋๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋์ผ๋ก ํด์ ํด ์ค๋ค.
๋ณดํต new ํค์๋๋ฅผ ์ฌ์ฉํด ๊ธฐ๋ณธ ํฌ์ธํฐ(raw pointer)๊ฐ ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ด๊ธฐํํ ํ์, ๊ธฐ๋ณธ ํฌ์ธํฐ๋ฅผ ์ค๋งํธ ํฌ์ธํฐ์ ๋์ ํ์ฌ ์ฌ์ฉํ๋ค. ์ด๋ ๊ฒ ์ ์๋ ์ค๋งํธ ํฌ์ธํฐ์ ์๋ช ์ด ๋คํ๋ฉด, ์๋ฉธ์๋ delete ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋์ผ๋ก ํด์ ํ๋ค. ๋ฐ๋ผ์ new ํค์๋๊ฐ ๋ฐํํ๋ ์ฃผ์๊ฐ์ ์ค๋งํธ ํฌ์ธํฐ์ ๋์ ํ๋ฉด, ๋ฐ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ ํ์๊ฐ ์์ด์ง๋ค.
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์ ํ๋์ ํน์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ์ค๋งํธ ํฌ์ธํฐ๊ฐ ์ด ๋ช ๊ฐ์ธ์ง๋ฅผ ์ฐธ์กฐํ๋ ์ค๋งํธ ํฌ์ธํฐ์ด๋ค.
์ด๋ ๊ฒ ์ฐธ์กฐํ๊ณ ์๋ ์ค๋งํธ ํฌ์ธํฐ์ ๊ฐ์๋ฅผ ์ฐธ์กฐ ํ์(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::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;
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
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(์ธ์ )
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
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();
#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<>