โ ์ฐธ์กฐ์(Reference)
์ฐธ์กฐ์๋ ํฌ์ธํฐ์ ์๋นํ ์ ์ฌํ ๊ฐ๋ ์ด๋ค. C์์๋ ํฌ์ธํฐ๋ง ์์์ง๋ง C++์์๋ ์ฐธ์กฐ์(Reference)๋ผ๋ ๊ฐ๋ ์ด ๋์ ๋๋ฉด์ ์ข ๋ ํธํ๊ฒ ์ฃผ์๊ฐ์ ์ ๊ทผํ ์ ์๊ฒ ๋์๋ค. ์ฌ์ค C++์์๋ ํฌ์ธํฐ์ ์์กดํ๊ณ ์ถ์ง ์์๊ณ *๊ณผ ->๋ฅผ ์ค์ด๊ณ ์ถ์๋ค๊ณ ํ๋ค.
์ฐ๋ฆฌ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋นํ๊ณ ๋ณ์๋ผ๋ ๊ฒ์ผ๋ก ์ด๋ฆ์ ์ง์ด์ค๋ค. ์ฐธ์กฐ์๋ ์ด ์ด๋ฆ์ ๋ณ๋ช ์ ๋ถ์ฌ์ฃผ๋ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค์ด '๊ทผํธ'์ ๋ณ๋ช ์ด '๊ทผ๋๋ฆฌ'๋ผ๊ณ ํ์ ๋ '๊ทผํธ'์๊ฒ ๊ณผ์๋ฅผ ์ฃผ๋ ๊ฒ๊ณผ '๊ทผ๋๋ฆฌ'์๊ฒ ๊ณผ์๋ฅผ ์ฃผ๋ ๊ฒ์ ๋์ผํ๋ค.
๊ฒฐ๊ตญ, ์ฐธ์กฐ์๋ ๋ ๋ค๋ฅธ ์ด๋ฆ์ ๋ถ์ฌํ๋ ๊ฒ๊ณผ ๊ฐ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
#include <iostream>
using namespace std;
int main()
{
int var = 10;
int &ref = var;
cout << var << endl;
cout << ref << endl;
cout << &var << endl;
cout << &ref << endl;
ref = 20;
cout << var << endl;
cout << ref << endl;
}
// ์คํ๊ฒฐ๊ณผ
// 10
// 10
// 0004D7F3
// 0004D7F3
// 20
// 20
์ฝ๋์์ ์ฐธ์กฐ์์ var๋ ๊ฒฐ๊ตญ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๊ณต๊ฐ์ ๋ฐ๋ผ๋ณด๊ธฐ ๋๋ฌธ์ ๊ฐ๊ณผ ์ฃผ์ ๊ฐ ๋ชจ๋ ๊ฐ๋ค.
โ Call by Pointer vs Call by Reference
#include <iostream>
using namespace std;
void swapByPointer(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swapByReference(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int var1 = 55;
int var2 = 77;
swapByPointer(&var1, &var2);
cout << var1 << endl;
cout << var2 << endl;
swapByReference(var1, var2);
cout << var1 << endl;
cout << var2 << endl;
}
// ์คํ๊ฒฐ๊ณผ
// 77
// 55
// 55
// 77
Call by Value์ Call by Reference๊ฐ ๋ ์ต์ํ๋ค. ์ฌ๊ธฐ์ ๋ ํผ๋ฐ์ค๋ ์ฐธ์กฐ์๋ฅผ ์๋ฏธํ๋ค๊ธฐ ๋ณด๋จ ๋ ๋์ ๋ฒ์๋ก ๊ฐ๋ง ๋ณต์ฌ ํ๋ ํ๋ผ๋ฏธํฐ, ์๋ณธ ๊ฐ์ ์ฐธ์กฐํ๋ ํ๋ผ๋ฏธํฐ๋ก ์ฐ์ธ๋ค.
C++์์๋ Call by Reference์ ๋ ๊ฐ์ง, ํฌ์ธํฐ์ ์ฐธ์กฐ์๋ก ํจ์ ์ธ์ ์ ๋ฌ ๋ฐฉ์์ด ์๊ณ ๊ทธ ์ฐจ์ด๊ฐ ์ ์ฝ๋์ด๋ค. ์ฝ๋๋ ๋ฌธ์ ์๋ค.
์ฌ๋ฌ๋ถ๋ค์ด ๋ณด๊ธฐ์ ์ด๋ ์ชฝ์ด ๋ ๋ณด๊ธฐ ํธํ๊ณ ์ฐ๊ธฐ ํธํ๊ฐ? 10๋ช ์ค 10๋ช ์ ์ฐธ์กฐ์์ ์ํ ๋ฐฉ์์ด ์ข๋ค๊ณ ํ ๊ฒ์ด๋ค. ํฌ์ธํฐ์ฒ๋ผ ์ฃผ์๊ฐ ์ฐ์ฐ์(&)์ ํฌ์ธํฐ ๊ฐ์ ์ ๊ทผํ๊ธฐ ์ํ ์ฐ์ฐ์(*)๋ฅผ ์ธ ํ์๊ฐ ์๋ค.
์ฐธ์กฐ์์ ์ํ ์ ๋ฌ ๋ฐฉ์์์ ํ๋ผ๋ฏธํฐ int &a, int &b๋ ์ค์ ์ ๋ฌ๋ ์ธ์ var1, var2๊ฐ ๋์ ๋์ a, b๊ฐ ๊ฐ๊ฐ var1, var2๋ฅผ ์ฐธ์กฐ(๋ณ๋ช ์์ฑ)ํ๋ ๋ฐฉ์์ด๋ค. ๋ฐ๋ผ์ a, b๊ฐ ๋ณ๊ฒฝ๋๋ฉด var1, var2๋ ๋น์ฐํ ๋ณ๊ฒฝ๋๋ค.
โ ์ฐธ์กฐ์(Reference)์ ํฌ์ธํฐ(Pointer)์ ์ฐจ์ด์
์ฐธ์กฐ์๊ฐ ๋จ์ํ ์ฐ๊ธฐ ํธํด์ ์ฐ๋ ๊ฒ์ผ๊น? ๊ทธ ์ธ ํฌ์ธํฐ์ ๋ค๋ฅธ ์ ์ด ํ๋๋ ์์๊น?
์ฐจ์ด์ ์ด ์๋ค.
โ๏ธ์ฒซ ๋ฒ์งธ, ์ฐธ์กฐ์๋ Null์ ํ์ฉํ์ง ์๋๋ค.
์ฐธ์กฐ์๋ ์ ์ธ์ ๋ฐ๋์ ์ด๋ค ๋์์ ์ฐธ์กฐํด์ผ๋ง ํ๋ค. int &ref; ํน์ int &ref = nullptr;์ ๋ถ๊ฐ๋ฅํ๋ค. ๋ณดํต ์ฐ๋ฆฌ๊ฐ ๋ณ๋ช ์ ์ง์ ๋ ๋ณ๋ช ๋ถํฐ ์ง์ด๋๊ณ ๊ทธ ๋์์ ์ฐพ์ง ์๋๋ค. ๋์์ ์๊ฐํ๋ฉด์ ๋ณ๋ช ์ ์ง๋ ๊ฒ๊ณผ ๋์ผํ๋ค.
์ด ๋ถ๋ถ์ด ์ฐธ์กฐ์๊ฐ ์์ ์ฑ์ ๊ฐ์ถ๊ณ ์๋ค๋ ์ ์ด๋ค. ํฌ์ธํฐ๋ null์ ํ์ฉํ๊ธฐ ๋๋ฌธ์, null์ ์๋ชป ์ ๊ทผํ๋ฉด SIGSEGV๋ฅผ ๋ง๋๊ฒ ๋๋ค. ๊ทธ๋์ ํฌ์ธํฐ ๊ฐ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํญ์ ํด์ค์ผํ์ง๋ง ์ฐธ์กฐ์๋ ๊ทธ๋ด ํ์๊ฐ ์๋ค.
โ๏ธ๋ ๋ฒ์งธ, ์ฐธ์กฐ์๋ ์ฐธ์กฐ ๋์์ ๋ณ๊ฒฝํ ์ ์๋ค.
ํฌ์ธํฐ๋ก ์ ์ธ๋ ptr1์ด var1์ ๊ฐ๋ฆฌํค๊ณ ์๋ค๊ณ ๊ฐ์ ํ์. ptr1์ด var2๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ๋ณ๊ฒฝํ๋ค. ๋ฌธ์ ๊ฐ ์๋ค. ํ์ง๋ง ์ฐธ์กฐ์๋ ์ด๋ฅผ ํ์ฉํ์ง ์๋๋ค.
์๋ ์ฝ๋๋ฅผ ๋ณด์.
#include <iostream>
using namespace std;
int main()
{
int var1 = 5;
int var2 = 3;
int &ref1 = var1;
ref1 = var2;
cout << &var1 << endl;
cout << &var2 << endl;
cout << &ref1 << endl;
cout << var1 << endl;
cout << var2 << endl;
cout << ref1 << endl;
}
// ์คํ๊ฒฐ๊ณผ
// 000CA683
// 000CF42B
// 000CA683
// 3
// 3
// 3
๋ง์ฝ ref1์ด ์ฐธ์กฐํ๊ณ ์๋ ๋ณ์๋ฅผ var2๋ก ๋ฐ๊พธ๋ ค๊ณ ref1 = var2๋ฅผ ํ๋ฉด ์๋ํ ๋๋ก ์๋ํ์ง ์๋๋ค. ์ด๋ var1 = var2๋ฅผ ์คํํ ์ ์ด ๋๋ค. ๋ฐ๋ผ์ ์ฌ์ ํ ref1์ var1๊ณผ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ๊ณ ์๊ณ , ๊ฐ๋ง 5์์ 3์ผ๋ก ๋ณต์ฌ๋์๋ค.
ํน์ ํท๊ฐ๋ฆฐ๋ค๋ฉด ref1์ ๋ชจ๋ var1๋ก ๋ฐ๊ฟ ๋ณด๋ฉด ์ดํด๊ฐ ๋น ๋ฅผ ๊ฒ์ด๋ค.(์ด๋ฆ๊ณผ ๋ณ๋ช ์ ๋์ผํ ์ฌ๋์ด๋๊น)
โ๏ธ์ธ ๋ฒ์งธ, ์ฐธ์กฐ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์๋ชจํ์ง ์๋๋ค.
ํฌ์ธํฐ๋ ์ฃผ์ ๊ฐ์ ์ ์ฅํ๊ธฐ ์ํด ๋ณ๋์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์๋ชจํ๋ค. ํ์ง๋ง ์ฐธ์กฐ์๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐธ์กฐํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์๋ชจํ์ง ์๋๋ค.
์ด๋ Call by Reference์์๋ ์ธ์ ์ ๋ฌ์ ์ํ ๋ฉ๋ชจ๋ฆฌ ์๋ชจ๊ฐ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์ธก๋ฉด์์๋ ํฌ์ธํฐ๋ณด๋ค ํจ์จ์ ์ด๋ค.
โ ์ค๋ฌด์์์ ์ฐธ์กฐ์ ์ฌ์ฉ
// Function Parameter
inline void updateLastPrices(const std::string& symbol, const std::pair<double, double>& prices)
{
std::lock_guard<std::mutex> lk(lastPricesMx);
lastPrices[symbol] = prices;
}
// Reference
for (const auto& elem : Data)
{
const auto& type = elem.firstReq.detail.type;
auto& ticket = elem.firstReq.detail.ticket;
if ( type == CHANGE )
{
ticket += 10;
}
}
์ค๋ฌด์์๋ Call by Reference๋ฅผ ๋งค์ฐ ๋ง์ด ์ฌ์ฉํ๋ค. ์ด์ฉ ์ ์์ด ํฌ์ธํฐ๋ฅผ ๋๊ฒจ์ผ ํ ๋๋ฅผ ์ ์ธํ๊ณ ๋ ๋๋ถ๋ถ์ ํด๋์ค ์ธํด์ค๋ฅผ ์ฐธ์กฐ์๋ก ๋๊ธด๋ค.
์ฌ๊ธฐ์ ์์ฃผ ์ฐ๋ ํจํด์, INPUT๊ฐ์ const XXXX&, OUTPUT๊ฐ์ XXXX& ํํ๋ก ๋๊ธด๋ค. ์ฆ, ๊ฐ์ ์ํ ๋ณต์ฌ๊ฐ ์ด๋ฃจ์ด์ง์ง ์๋๋ก ์ฐธ์กฐ์๋ฅผ ์ฐ๋, const๋ฅผ ๋ถ์ฌ์ ์์์์ ๋ณด์ฅํ๊ณ , ์๋ณธ ๊ฐ์ ๋ณ๊ฒฝ์ด ํ์ํ ๊ฒฝ์ฐ์๋ง const๋ฅผ ๋ถ์ด์ง ์๋ ๋ฐฉ์์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ฐธ์กฐ์๋ฅผ ๋ณ์นญ์ฒ๋ผ ์ฐ๋ ๋ฐฉ์์ด ์๋ค.(์ฝ๋์์ Reference๋ถ๋ถ). elem.firstReq.detail.XXXX์ ๊ฐ์ด ๋ณ์๊ฐ ์ฌ๋ฌ ๋ฒ ํด๋์ค ํํ๋ก ๋ฉค๋ฒ๋ณ์๋ฅผ ๊ฐ์ง ๋ ์ฐธ์กฐ์๋ก ํด๋น ๋ณ์๋ฅผ ๋ณ๋ช ์ผ๋ก ๋ง๋ ๋ค.
๊ทธ๋ฆฌ๊ณ ํธํ๊ฒ ์ค์ฌ์ type, ticket๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ค. ์ฌ๊ธฐ์ type์ ๋ณ๊ฒฝ๋ ์ผ์ด ์์ผ๋ฏ๋ก const auto& type; ์ผ๋ก ํํํ๊ณ , ticket์ ๋ณ๊ฒฝ์ด ์์ผ๋ฏ๋ก const๋ฅผ ๋บ๋ค.
์ด์ฒ๋ผ ์ฐธ์กฐ์๋ ์๋ณธ ๊ฐ์ ๋ณ๊ฒฝ์ด ์๋ ๊ฒฝ์ฐ์๋ const๋ฅผ ๋ถ์ด๋ ๊ฒ์ด ์ข๋ค.
'C++ ๊ธฐ์ด' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[C++] 16-1. ์์(Inheritance)๊ณผ ๊ฐ์ ํจ์(Virtual Function) (0) | 2023.06.23 |
---|---|
[C++] 15. ํด๋์ค(class)์ ๊ตฌ์กฐ์ฒด(struct) (0) | 2023.06.09 |
[C++] 13-2. ๊ธฐ๋ณธ์ ์ถ๋ ฅ๊ณผ ํ์ผ์ ์ถ๋ ฅ(feat. iostream, ifstream, ofstream, stringstream) (0) | 2023.05.19 |
[C++] 13-1. ์ ์ถ๋ ฅ(feat. ํ์ค์ ์ถ๋ ฅ๊ณผ ํ์ผ์ ์ถ๋ ฅ) (2) | 2023.05.17 |
[C++] 12. ๋ฌธ์์ด(feat. ์ง๋ ฌํ) (0) | 2023.05.06 |
๋๊ธ