ํด๋์ค์ ์๋ฃ๋ฉค๋ฒ๋ค์ ๊ตฌํํด๋์ค(or ๊ตฌ์กฐ์ฒด)๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๋ก ๋์ฒดํ์. (์ด๋ฐ์ง์ pimpl ๊ด์ฉ๊ตฌ๋ผ๊ณ ํ๋ค.)
ํด๋์ค ํด๋๊ฐ์ ์์กด์ฑ์ด ํด์๋ก ์ปดํ์ผ์ด ๋ฆ์ด์ง๊ณ ์ปดํ์ผ ๋ฒ์๋ ์ปค์ง๋ค. ๊ทธ๋ฌ๋ ์์กด์ฑ์ ์ค์ฌ๋ณด์. (๊ทธ์ธ ํด๋์ ์คํ๋๋ฉด ๋น๋ ์๋ฌ ๋๋ฐ)
//widget.h
#include "gadget.h"ย
#include <string>
#include <vector>
class Widget_98
{
public:
Widget_98() {};
~Widget_98() {};
private:
std::string name;
std::vector<double> data;
Gadget g1, g2, g3;ย ย //Gadget ์ฌ์ฉ์ ์ ์ Class
};
/**
1. widget์ ๋ฐ๋์ ๋ฉค๋ฒ๋ณ์ ํ์
์ ์์ ์๋ ํด๋๋ฅผ include ํด์ผํ๋ค.
2. gadget.h๊ฐ ๋ฐ๋๋ฉด widget.h๋ฅผ includeํ๊ณ ์๋ ๋ชจ๋ ํ์ผ์ด ์ปดํ์ผ์ ์ํฅ์ ๋ฐ๋๋ค->์์กด์ฑ ์๊น
*///widget.h
class Widget_98
{
public:
Widget_98();
~Widget_98();
private:
ย struct Impl; //๋จ์ ์ ์ธ๋ง , ์ด๋ ๊ฒ ์ ์ธ๋ง ํ๊ณ ์ ์๋ ํ์ง ์๋ ํ์์ ๋ถ์์ ํ์(imcomplete type)์ด๋ผ๊ณ ํ๋ค.
ย Impl *pImpl;
};
/** widget.h ์์ ์ฌ๋ฌ ํด๋๋ฅผ ํฌํจํ ํ์๊ฐ ์๋ค.*/
//widget.cpp
#include "widget.h"
#include "gadget.h"
#include <string>
#include <vector>
struct Widget_98::Impl { //์ ์
ย std::string name;
std::vector<double> data;
Gadget g1, g2, g3;
};
Widget_98::Widget_98()ย : pImpl(new Impl){}
Widget_98::~Widget_98() {delete pImpl;}
ย /** ๊ตฌํ๋ถ์์ ํ์ํ ๋ถ๋ถ๋ง include, ์์กด์ฑ์ด .h์์ .cpp๋ก ์ฎ๊ฒจ์ก๋ค.*/raw ํฌ์ธํฐ ์ฌ์ฉ ํ๋๊ฒ new & delete ํธ์ถ์ด ์์ ์์ ์ด๋ค. 'Widget ์์ฑ์์์ Widget::Impl๊ฐ์ฒด๋ฅผ ํ ๋นํ๊ณ Widget์ด ํ๊ดด๋ ๋ ๊ทธ ๊ฐ์ฒด๋ฅผ ํด์ ํด์ค์ผํ๋ค'๋ ๊ด์ ์์ std::unique_ptr(ํด๋์ค ๋ ์ ์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ)์ ์จ์ผํ๋ค. ๋ผ๊ณ ์ ์๊ฐ ์ฃผ์ฅ.. ์๋ฟ์ง๋ ์๋๋ค...
// widget.h
#include <memory>ย
class Widget
{
public:
Widget();
//~Widget();ย ย //์๋ฉธ์ ์ ๊ฑฐ
private:
struct Impl;
ย std::unique_ptr<Impl> pImpl; ย //์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ์
};
// widget.cpp
...
//ํญ๋ชฉ 21์ ๋ฐ๋ผ make_unique ์ฌ์ฉ
Widget::Widget()ย : pImpl(std::make_unique<Impl>()){}
....
int main()
{
Widget w; //์ฌ๊ธฐ์ ์๋ฌ๊ฐ ๋์ผํ๋๋ฐ visual c++ 2017์์ ์๋๋ค?
return 0;
}
์๋์์ฑ๋๋ ์๋ฉธ์์ฝ๋์์ unique_ptr์ด delete๋ฅผ ํธ์ถํ ๋ ์ปดํ์ผ๋ฌ์์ ๋ถ์์ ํ์์ ์ฒดํฌ (static_asser)ํ๋ค.
//std::unique_ptr <Widget::Impl>๋ฅผ ํ๊ดดํ๋ ์ฝ๋๊ฐ ๋ง๋ค์ด์ง๋ ์์ ์ Widget::Impl์ด ์์ ํ ํ์์ด๋๊ฒ ํ๋ฉด ๋ฌธ์ ๊ฐ ํด๊ฒฐ
//์ ์ฝ๋์์ widget.h์
class Widget{
public:
Widget();
~Widget();ย ย //์ ์ธ๋ง
...
};
//widget.cpp์
Widget::~Widget(){}ย //์๋ฉธ์ ์ ์
//์ด๋ ๊ฒ ํ๋ฉด Widget::Impl์ด ์ ์๋์ด ์์ด ์์ ํ ํ์์ด ๋ํ Widget์ด ์ ์ธ๋์๋ค.๊ตฌํํ์ผ์ ์๋ฉธ์๋ฅผ ์ ์ธํ ์๋ฏธ๋ฅผ ๊ฐ์กฐํ๋ ์ฉ๋๋ก
Widget::~Widget() = default;##์ฃผ์ ํ ์ ? ์๋ฉธ์๋ฅผ ์ ์ ํ๊ธฐ ๋๋ฌธ์ ์ด๋์ฐ์ฐ์ด ๋ํดํธ๋ก ๋ง๋ค์ด์ง์ง ์๋๋ค.์ด๋์ ์ง์ํ๋ ค๋ฉด ์ง์ ์ ์ธํด์ผํ๋ค.
class widget{
...
Widget(Widget&& rhs) = default;
Widget& operator=(Widget&& rhs) = default ;
//์ด๋ ๊ฒ ํด๋์ค์ ์ ์ธํ๋ฉด ๋ ๊ฒ ๊ฐ์ง๋ง
//์ด๋ ๋ฐฐ์ ์ฐ์ฐ์๋ pImpl์ ์ฌ์ ์ ํ๊ธฐ์ ์ pImpl์ด ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ฅผ ํ๊ดดํด์ผํ๋๋ฐ ์ด๋ Impl์ด ๋ถ์์ ํ์
์ด๋ผ์ ์๋ฌ
//์ด๋ ์์ฑ์๋ ์ด๋์์ฑ์ ์์์ ์์ธ๋ฐ์ํ์๋ ์ฒ๋ฆฌํ๋ ์ฝ๋๋ฅผ ๋ง๋๋๋ฐ ์ด๋ pImpl๋ฅผ ํ๊ดดํ๋ ค๋ฉด Impl์ด ์์ ํ์์ด์ด์ผ ํ๋ค.
//๋ฐ๋ผ์ ์๋ฌ. ํ์ง๋ง visual c++ 2017์ ์๋๋ค....ใ
กใ
ก
...
};
//ํด๊ฒฐ๋ฒ? ๋ถ์์ ํ์
์ ํด๊ฒฐํด์ค์ผํ๋ค..
//widget.h
class widget{
...
Widget(Widget&& rhs);ย ย ย ย //์ฌ๊ธฐ์
Widget& operator=(Widget&& rhs);ย //์ ์ธ
...
}
//Widget.cpp
struct Widget::Impl {ย std::string name;ย std::vector<double> data;ย Gadget g1, g2, g3;};
Widget::Widget()ย : pImpl(std::make_unique<Impl>()){}
Widget::~Widget() = default;
Widget::Widget(Widget&& rhs) = default;ย ย ย ย ย //์ฌ๊ธฐ์
Widget&ย Widget::operator=(Widget&& rhs) = default;ย ย //์ ์
...์์กด์ฑ์ ์ค์์๋ฟ ํด๋์ค๊ฐ ๋ฐ๋์ง ์๋๋ค.์ฌ์ฉํ๋ ์๋ฃ ๋ฉค๋ฒ๊ฐ ๋ณต์ฌ๊ฐ ๊ฐ๋ฅํ์์ด๋ผ๋ฉด widget์ญ์ ๋ณต์ฌ๋ฅผ ์ง์ํด์ผํ๋ค. ๊ทธ๋ฐ๋ฐ ๋ณต์ฌ ์ฐ์ฐ์ ์ง์ ์ ์ ํด์ค์ผํ๋ค. ์ด์ 1) std:unique_ptr๊ฐ์ ์ด๋ ์ ์ฉ ํ์์ด ์๋ ํด๋์ค์ ๋ํด ์ปดํ์ผ๋ฌ๊ฐ ๋ณต์ฌ ์ฐ์ฐ์ ๋ง๋ค์ด์ฃผ์ง ์๋๋ค. ์ด์ 2) deep copy๋ฅผ ํด์ผํ๊ธฐ ๋๋ฌธ.
๋ ์ ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ std:unique_ptr์ ์ฌ์ฉํ๋ค. ์๋ฉธ,์ด๋ ์ฐ์ฐ์ ๋ถ์์ ํ์ ์ ํด๊ฒฐํด์ค์ผํ๋ค.
๋ ์ ๊ฐ์ฒด๊ฐ ์๋ std::shared_ptr๋ก ๊ตฌํํ๊ฒฝ์ฐ ์๋ฉธ,์ด๋ ์ฐ์ฐ์ ๋ฐ๋ก ์์ฑํ ํ์๊ฐ ์๋ค. ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ ํน์ ๋ฉค๋ฒ ํจ์๋ค์ด ์ฐ์ด๋ ์์ ์์ ํผ์ง์นญ ํ์๋ค์ด ์์ ํ ํ์์ด์ด์ผ ํ๋ค๋ ์๊ตฌ ์กฐ๊ฑด์ด ์ฌ๋ผ์ง๋ค.(์๋ฉธ,์ด๋ ์ฐ์ฐ์์ ๊ฒฐ๊ตญ delete์ static_assert์ฒดํฌ๊ฐ ์๋?)