[CPP Module] 04
๊ธฐ๋ณธ ๊ท์น
Orthodox Canonical Form
- ์์ฑ์
- ๋ณต์ฌ ์์ฑ์
- ๋ณต์ฌ ํ ๋น ์์ฑ์
- ์๋ฉธ์
์ด 4๊ฐ์ง๋ฅผ ํฌํจ
- include guards
- ์ฝ๋ ๋ถํ ์ ์ํด ํ์ํ ๊ฒฝ์ฐ ์ถ๊ฐํ์ผ ์ฌ์ฉ๊ฐ๋ฅ
- C++ ์ญ์ new๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์๋ ์ ์๊ธฐ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ํ ๋์๋ฐฉ์ง๋ฅผ ํด์ค์ผํ๋ค
ex00 : Polymorphism
์์์ด๋ผ๋ ๊ฐ๋ ์ ์์ฉํด์ ์จ๋ณด๋ ๊ณผ์
new
c์ธ์ด์ malloc์ด๋ free์ ๋๊ฐ์ด c++์๋ ๋์ ํ ๋น์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ณ ํด์งํ๋ ๊ฒ์ด ์กด์ฌํ๋ค.
new์ ๊ฒฝ์ฐ์๋ ์์ฑ์๋ฅผ ํธ์ถํ๊ณ , delete์ ๊ฒฝ์ฐ์๋ ์๋ฉธ์๋ฅผ ํธ์ถํ๋ค.
class* a = new class; // ์์ฑ์ ํธ์ถ
.
.
.
delete a; // ์๋ฉธ์ ํธ์ถ
์์ ๊ฐ์ ํ์์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๊ฑฐ๋ ํด์ ๋ฅผ ์งํํ๋ค.
๋์ ํ ๋น์ ์ ํด์ผํ๋๊ฐ?
int a[5];
์์ ๊ฐ์ ๋ฐฉ๋ฒ์ด๋ malloc, free or new, delete์ ๋๊ฐ์ด ๋์์ ํ์ง๋ง ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๊ณ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ํ ๋น์ ์์ผ๋ฒ๋ฆฌ๋ฉด ํ๋ก๊ทธ๋จ์ด ๋๋ ๋๊น์ง ๊ณ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋จน๊ณ ์์ผ๋ ๊ทธ๋งํผ ๋ฉ๋ชจ๋ฆฌ์ ํจ์จ์ ๋จ์ด์ง๊ฒ๋๋ค.
๊ทธ๋์ ๋์ ํ ๋น์ด๋ผ๋ ๊ฒ์ ์ฌ์ฉํ์ฌ ์ฌ์ฉํ ๋๋ง malloc์ด๋ new๋ฑ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ก์๋ค๊ฐ ํ์์์ผ๋ฉด free๋ delete๋ก ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ํด์ ํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ด๋ค.
์ ์บ์คํ (up casting), ๋ค์ด ์บ์คํ (down casting)
์ ์บ์คํ (up casting)
class Animal {
// ...
};
class Cat : public Animal {
// ...
};
int main(void) {
const Animal* temp = new Cat();
return 0;
}
Animal
|
Cat
์์์๋ class๊ฐ ์์ ๊ฐ์ ํ์์ผ๋ก ์์์ด ์ด๋ฃจ์ด์ง๊ณ ์์๋ cat์ด๋ผ๋ ํด๋์ค๊ฐ animal์ด๋ผ๋ ํด๋์ค๋ก ์ ์บ์คํ ์ด ์ด๋ฃจ์ด์ง ์ํฉ์ผ๋ก temp๋ผ๋ class๋ ๋ถ๋ชจํด๋์ค์ ๋ฉค๋ฒ์๋ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค.
๋ค์ด ์บ์คํ (down casting)
// error
Animal *a = new Animal();
Cat c = (Cat) a;
// answer
Animal* a = new Cat();
Cat c = (Cat) a;
๋ค์ด ์บ์คํ ์ ๋ง ๊ทธ๋๋ก ๋ถ๋ชจํด๋์ค → ์์ํด๋์ค ํํ๋ก ํ๋ณํ์ ํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ๋ถ๋ชจํด๋์ค๋ฅผ ์์ํด๋์ค๊ฐ ์์๋ฐ์์ ธ ์๋ ์ํฉ์์๋ ์์ํด๋์ค๊ฐ ๋ถ๋ชจํด๋์ค๋ณด๋ค ๊ฐ์ง๊ณ ์๋ ์ ๋ณด๊ฐ ๋ง์ ์ํฉ์ด ๋ณดํต์ด๋ฃจ์ด์ง๋ค.
๊ทธ๋ ๋ถ๋ชจํด๋์ค๋ฅผ ์์ํด๋์ค๋ก ๋ค์ด์บ์คํ ์ ํด๋ฒ๋ฆฌ๋ฉด ๋ถ๋ชจํด๋์ค์ ์ ๋ณด๋ง์ผ๋ก๋ ์์ํด๋์ค๊ฐ ๊ตฌ์ฑ๋ ์ ์๊ธฐ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์์ด ๋๋ ํ์์ด๋ค.
๊ทธ๋์ ๋ค์ด์บ์คํ ์ ํ๊ณ ์ถ์ผ๋ฉด ํ์์ ๊ฐ์ด ์ ์บ์คํ ์ด ์ ํ๋ ์ดํ๊ฐ ์ฌ์ฉ์ ํด์ผํ๋ค.
[Java] ์ ์บ์คํ ๊ณผ ๋ค์ด์บ์คํ
์ด๋ ํ ์๋ฃํ/ํด๋์ค์ ๋ณ์/๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค๋ ๊ฒ์, ์ข๋ณ์ ์๋ฃํ์ด ์๊ตฌํ๋ ์ ๋ณด๋ฅผ ๋ชจ๋ ์ฐ๋ณ์ด ๊ฐ์ถ์์ ๋ ๊ฐ๋ฅํ ๊ฒ์ด๋ค.์บ์คํ ์ ํ๋ณํ์ ์๋ฏธํ๋๋ฐ ์ด ํ๋ณํ ๋ํ, ์์ ๋ง์ถฐ์ ์
velog.io
ex01 : I don’t want to set the world on fire
ํด๋์ค์์์ ๋ค๋ฅธ ํด๋์ค๋ฅผ ๊ฐ์ง๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด๋ ๊ฒ
๊น์ ๋ณต์ฌ๋ผ๋ ๊ฒ์ ์ดํดํ๊ณ ์ฌ์ฉํด๋ณด๊ธฐ
leaks ํ์ธ
system("leaks a.out");
์์ ๊ฐ์ ํ์์ ์ฝ๋๋ฅผ ์ข ๋ฃ ์ง์ ์ ๋ฃ์ด๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๋์ง ์ํ๋์ง ๋ฑ์ system์์ ์คํํ์ฌ ํด๋น๋ถ๋ถ์ ํ์ธํด์ค๋ค.
double free ํ์ธ๋ฐฉ๋ฒ (๋ฉ๋ชจ๋ฆฌ ๋ฒ๊ทธ ๋๋ ํฐ)
-g3 -fsanitize=address
์์ ๊ฐ์ ํ๋๊ทธ ์ต์ ์ ๋ฃ์ด์ ์ปดํ์ผ์ ์งํํด๋ณด๋ฉด double free๋ฑ ํ๋ก๊ทธ๋จ์ ๋ฌธ์ ๊ฐ ๋ญ๋๋ฌธ์ ๋ฐ์์ด ๋์ด ๋์ค์ ์ข ๋ฅ๊ฐ ๋์๋์ง๋ฅผ ํ์ธํ ์ ์๋ ์ต์
( ์์ ๊ฐ์ ์ฌ์ง์ฒ๋ผ ์ด๋์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์๊ณ ์ ๋ฐ์ํ์๋์ง ์ค๋ฅ๋ฅผ ์๋ ค์ค๋ค. )
๊น์ ๋ณต์ฌ์ ์์ ๋ณต์ฌ
๋ฌธ์ ์์๋ ๊ฐ์ฒด๊ฐ ๋ณต์ฌ๊ฐ shallow copy๊ฐ ์๋ deep copy๋ฅผ ํ๋๋ก ์๊ตฌ๋ฅผ ํ๊ณ ์๋ค.
์ฌ๊ธฐ์์ ๊น์ ๋ณต์ฌ์ ์์ ๋ณต์ฌ๋ ๋ฌด์์ด๊ณ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ?
์์ ๋ณต์ฌ ( shallow copy )
์ค์ ๋ฐ์ดํฐ๊ฐ ์๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฃผ์๋ง์ ๋ณต์ฌ
class *test = new class();
class *copy = new class();
*test = *copy;
delete test;
delete copy;
// [1] 80684 segmentation fault
์์ ๋ณต์ฌ๋ฅผ ์งํํ ๊ฒฝ์ฐ์ ์์ ์ฝ๋๋ฅผ ์งํํ ๊ฒฝ์ฐ test์ copy๋ชจ๋ 1๊ฐ์ ๊ฐ์ ๊ฐ๋ฅดํค๊ณ ์๊ธฐ๋๋ฌธ์
๊ฐ์ ๊ฐ์ delete๋ฅผ 2๋ฒ ์งํ์์ผ segmentation fault error๊ฐ ๋ฐ์์ด๋๋ค.
๊ทธ๋์ test์ ๊ฐ์ ๋ฐ๊พธ๊ฑฐ๋ copy์ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ๋ณ๊ฒฝ๋ ๊ฐ์ด ๋ชจ๋์๊ฒ ์ ์ฉ์ด ๋๋ค.
๊น์ ๋ณต์ฌ ( deep copy )
๊ฐ ์์ฒด๋ฅผ ๋ณต์ฌ
class *test = new class();
class *copy = new class();
*test = *copy;
delete test;
delete copy;
// not error
๋ด๋ถ์ ์ผ๋ก ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ๊ตฌ์ฑํ๋์ ๋ฐ๋ผ ๊น์ ๋ณต์ฌ๋ฅผ ์งํํ ๊ฒฝ์ฐ์๋ ์์ ๋ณต์ฌ์๋ ๋ค๋ฅด๊ฒ test์ copy๊ฐ ๊ฐ์ ์๋ก ๋ค๋ฅธ ์ฃผ์๊ฐ์ ๊ฐ์ ๋ค๊ณ ์๊ธฐ๋๋ฌธ์ delete๋ฅผ 2๋ฒ ์งํํด๋ error์์ด ์ฝ๋๊ฐ ์งํ์ด ์ด๋ฃจ์ด์ง๋ค.
๋ด๋ถ์ ์ผ๋ก ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ๊ตฌ์ฑํ๋์ ๋ฐ๋ผ ์์ ๋ณต์ฌ์ ๋ค๋ฅด๊ฒ test์ copy๊ฐ ์๋ก ๋ค๋ฅธ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์๊ธฐ๋๋ฌธ์ ๊ฐ์ ๋ฐ๊พธ์ด๋ ๊ฐ์๋ง ๊ฐ์ด ๋ณ๊ฒฝ์ด ๋๋ค.
ex02 : Abstract class
abstract class ์ถ์ ํด๋์ค์ ๋ํด์ ๋ค๋ฃจ๋ ํํธ
pure virtual function (์์ ๊ฐ์ ํจ์)
ํ์ ํด๋์ค์ ์ํด ์ฌ์ ์๋์ด์ผ ํ๋ ํจ์
virtual void test() = 0;
ํจ์๋ฅผ ์ ์ธ๋ง ํ๊ณ ์ฌ์ฉํ์ง ์์ ์ํ๋ก ํด๋นํจ์๋ฅผ ๊ฐ์ง๊ณ ์๋ ํด๋์ค๋ฅผ ์์๋ฐ์ ์์ ํด๋์ค์์ ์ฌ์ ์ธ ํ์ ์ฌ์ฉํ๋ ํจ์ (ํด๋น ํจ์๋ ์ ์ธ๋ง ๋์ด์๊ณ ์์ ๋ด์ฉ์ด ์๋ค๋ ์๋ฏธ์์ ์ ์ธ๋ถ ๋์ “= 0;”ํ์์ผ๋ก ํ์๋ฅผ ํด์ค๋ค.)
virtual void test();
์์ ๊ฐ์ ํ์์ผ๋ก ์์๋ฐ์ ์์ ํด๋์ค์์ ํจ์์ ๋ด์ฉ์ ์ฌ ์ ์ธํด์ค์ผํ๋ค.
abstract class (์ถ์ ํด๋์ค)
ํ๋ ์ด์์ ์์ ๊ฐ์ ํจ์๋ฅผ ํฌํจํ๊ณ ์๋ ํด๋์ค๋ฅผ ์ถ์ ํด๋์ค๋ผ๊ณ ๋ถ๋ฅธ๋ค.
class Test
{
private:
public:
virtual void sound() = 0; // ์์๊ฐ์ํจ์
};
class Test
{
private:
public:
virtual void sound() = 0;
};
class Copy : public Test
{
public:
virtual void sound() {
std::cout << "Hello";
}
};
int main(void)
{
Copy copy;
copy.sound(); // output : "Hello"
return (0);
};
์์ ๊ฐ์ด Test ํด๋์ค๋ฅผ Copy ํด๋์ค๊ฐ ์์๋ฐ์ ๊ฒฝ์ฐ์๋ Testํด๋์ค์์ ์๋ ์์๊ฐ์ํจ์์ธ sound()๋ฅผ
์ ์ธ ํด์ค์ผํ๋ค.
์ ์ธ์ ํด์ฃผ์ง์์ ๊ฒฝ์ฐ
unimplemented pure virtual method 'sound' in 'TestTwo’
๊ฐ์ํจ์๋ฅผ ๋ง๋ค์ด๋๊ณ ์์๋ฐ์ ์์ ํด๋์ค์์ ๋ฐ๋ก ์ ์ธ์ ํด์ฃผ์ง์๊ฒ๋๋ฉด ํด๋น ํจ์๋ฅผ ์ฐพ์ ์ ์๋ค๊ณ ํ๋ฉฐ ์ค๋ฅ๊ฐ ๋ฐ์๋๋ค.
์ถ์ํด๋์ค ์ฌ์ฉ์ฉ๋
์ถ์ํด๋์ค์ ๊ฒฝ์ฐ์๋ ์ด๋ฆ์์ ๋ณด์ด๋ค์ํผ ๊ตฌํ์ด ์๋ฒฝํ์ง ์์ ๋ ๋จ์ ์ผ๋ก ์ฌ์ฉ์ด ๋ถ๊ฐ๋ฅํ๊ณ ํ์ํด๋์ค์ ์ค๊ณ ๋๋ ๊ฐ์ด๋๋ผ์ธ์ ์ฃผ๋ ์ญํ ๋ง ํ๋ ํด๋์ค๋ก ์ฌ์ฉ๋๋ค.
class Test
{
private:
public:
virtual void sound() = 0;
};
int main(void)
{
Test test; // error
return (0);
}
์์ ๊ฐ์ด ์ ์ธ์ ํด์ ์ฌ์ฉ์ ํ ๋ ค๊ณ ํ๋ฉด ์ถ์ํด๋์ค๋ผ ๋ถ๊ฐ๋ฅํ๋ค๋ ๋ฌธ๊ตฌ๊ฐ ๋์จ๋ค.
virtual, override ์ฐจ์ด์
class Test
{
private:
public:
virtual void sound() = 0;
};
// ===== override =====
class TestOne : public Test
{
public:
void sound() override { // override
std::cout << "TestOne";
}
};
// ===== virtual ======
class TestTwo : public Test
{
public:
virtual void sound() { // virtual
std::cout << "TestTwo";
}
};
int main(void)
{
TestOne one;
TestTwo two;
one.sound(); // output : "TestOne"
two.sound(); // output : "TestTwo"
return (0);
}
์์ ๊ฐ์ด TestOne๊ณผ TestTwo์์๋ ๊ฐ๊ฐ Test๋ผ๋ ํด๋์ค๋ฅผ ์์๋ฐ์ override ํด์ฃผ์๋๋ฐ
one์ override์ฌ์ฉํ์๊ณ , two๋ virtual ์ฌ์ฉํ์๋ค.
๋๊ฐ์ง ๋ชจ๋ ๊ธฐ๋ฅ์ ์ผ๋ก๋ ๋๊ฐ์ด ์๋์ ํ๋๋ฐ ์ด๋ค ๋ถ๋ถ์์ ์ฐจ์ด์ ์ด ์๊ธฐ๋์ง ๋น๊ตํด๋ณด์๋ค.
override
C++11 ๋ฒ์ ์ด์๋ถํฐ ์ฌ์ฉ๊ฐ๋ฅํ ํค์๋๋ก ์์์ ๋ฐ๋ ํด๋์ค์์ override๋ฅผ ๋ฐ์ ๊ฒ์ ๋ช ์ํด์ฃผ๋ ์ญํ ์ ํ๋ค.
class Test
{
private:
public:
virtual void sound() = 0;
};
// ===== override =====
class TestOne : public Test
{
public:
void sound() const override { // const๋ก ์์ : error
std::cout << "TestOne";
}
};
์์๊ฐ์ด ์์๋ฐ์ ์์๊ฐ์ํจ์๋ฅผ ์์์ ์ผ๋ก ๋ณ๊ฒฝ์ ํ๋ฉด error๋ฅผ ๋ด๋ณด๋ด์ ๋ด๋ถ์ ์ผ๋ก ๋ฐฉ์ง๋ฅผ ํด์ฃผ๋ ์ญํ
๊ทธ์น๋ง ํด๋น๋ฐฉ๋ฒ์ ์์ฃผ ์ฌ์ฉ์ ํ๋๊ฑฐ๊ฐ์ง๋ ์๋ค.. ์์ง?
virtual
class Test
{
private:
public:
virtual void sound() = 0;
};
class TestTwo : public Test
{
public:
virtual void sound() { // virtual
std::cout << "TestTwo";
}
};
์์์ ๋ฐ๋ ํด๋์ค์์๋ virtual๋ฅผ ์์ ์ด๋ ํน๋ณํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง๋ ์์ง๋ง
์์์ ํด์ฃผ๋ ํด๋์ค๋ฟ๋ง ์๋๋ผ ์์์ ๋ฐ๋ ํด๋์ค์์๋ ๋ช ์์ ์ผ๋ก virtual๋ฅผ ์ ์ด์ฃผ๋๊ฒ์ด ์ข์ ์ฝ๋๋ผ๊ณ ํ๋ค.
Cat *cat = new Cat();
Dog *dog = new Dog();
Animal *cat = new Cat();
Animal *dog = new Dog();
Cat *cat = new Cat(); ์์ ๊ฐ์ ๋ฐฉ๋ฒ์ ๊ฒฝ์ฐ๋
virtual ~Animal();
์๋ฉธ์ ๋ํ virtual๋ก ์ ์ธ์ด ๋์ด์๋ค๋ฉด ์์ํด๋์ค์ ์๋ฉธ์๋ง ๋์์ ํด์ผํ๋๊ฑด ์๋์ง?
๋ถ๋ชจ์๋ฉธ์์ ์์์๋ฉธ์๊ฐ ๋ชจ๋ ๋์์ด ๋๋ค๋ฉด ์ ๋๋๊ฑด์ง?
ex03 : Interface & recap
ํด๋น ๊ณผ์ ์์๋ ์ง๊ธ๊น์ง ๋ฐฐ์ ๋ ๊ฐ๋ ๋ค์ ์์ฉํด์ ์กฐ๊ธ ๋ ๋ณต์กํ๊ณ ๋ค์ํ๊ฒ ์์์ ํด๋ณด๋ ํํธ
์๋ก์ด ๊ฐ๋ ์ด ํ์ํ๋ ํํธ๋ ์๋์ง๋ง
๊ธฐ์กด์ ๋ฐฐ์ ๋ ๊ฐ๋ ๋ค์ ์์ฉํ๊ณ ํ์คํ๊ฒ ์ฌ์ฉํด๋ด๋ผ ๋ผ๋ ๋๋์ ๊ณผ์ ์๋๊ฑฐ๊ฐ๋ค.
ํด๋น ๊ณผ์ ์์๋ 7๊ฐ์ ํด๋์ค๋ฅผ ์ ์ํด์ผํ๋ค.
- ICharacter
- Character
- IMateriaSource
- MateriaSource
- AMateria
- Ice
- Cure
๊ฐ๊ฐ ์ค๋ช ์ ํด๋ณด์๋ฉด
ICharacter, IMateriaSource ๋ interfaces ํ์์ผ๋ก ์ฌ์ฉ์ด ๋ ์๋ค์ด๊ณ
Character์๋ ICharacter ์ด๋ผ๋ interfaces๋ฅผ ์์ ๋ฐ์์ ์ฌ์ฉํ๋ฉฐ ๊ธฐ๋ณธ์ ์ธ user์ ํด๋นํ๋ ๊ฐ๋ค์ด ๋ด๊ธด๋ค.
user๋ MateriaSource๋ฅผ ํตํด ๋ง๋ค์ด์ง๋ ice์ cure๋ฅผ AMateria๋ฅผ ํตํด์ user์๊ฒ ์ ๋ฌ์ด ๊ฐ๋ฅํ๊ณ ํด๋น ์์๋ค์ ์ ๋ฌ๋ฐ์ user๋ ์์๋ค์ ์ฌ์ฉํ ์ ์๋ค.
์ ๋ฐฉ์ ์ธ
// AMateria.hpp
class AMateria
{
public:
virtual void use(ICharacter& target);
...
};
// ICharacter.hpp
class ICharacter
{
public:
virtual void equip(AMateria* m) = 0;
...
};
ICharacter์ AMateria๋ ์๋ก๋ฅผ ๋ด๋ถ ๋งค๊ฐํจ์์์ ์๋ก์ ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ณ ์์ด์ ์๋ก๋ฅผ ์ฐธ์กฐํ๊ฒ ๋์ด ์ปดํ์ผ์ด ์งํ์ด ๋์ง์๋๋ค.
// ICharacter.hpp
class AMateria;
class ICharacter
{
public:
virtual void equip(AMateria* m) = 0;
...
};
์ด ๋ถ๋ถ์ ํด๊ฒฐํด์ฃผ๊ธฐ์ํด์ ์ ๋ฐฉ์ ์ธ์ด๋ผ๋ ๋ฐฉ์์ ์ฌ์ฉํด์ ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ์์์ ์ธ์ ํด์ฃผ๋ฉด ์๋ก๋ฅผ ์ธ์ํด์ ์ค๋ฅ๊ฐ ๋ฐ์๋์ง์๊ฒ ๋๋ค.