๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๊ฒŒ์ž„๊ฐœ๋ฐœ

Xcode, C++ ์ด๋™ ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์•ˆ๋  ๋•Œ

์ตœ๊ทผ '์ด๊ฒƒ์ด C++์ด๋‹ค.'๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ๋Š”๋ฐ '4์žฅ ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ์ž„์‹œ ๊ฐ์ฒด' ํŒŒํŠธ์—์„œ ์•„๋ž˜ ์†Œ๊ฐœํ•˜๋Š” ์ฝ”๋“œ์˜ ๊ฒฐ๊ณผ๊ฐ€ ์ฑ…๊ณผ ๋‹ฌ๋ผ ๊ตฌ๊ธ€์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๋ธ”๋กœ๊ทธ, ์œ ํŠœ๋ธŒ๋ฅผ ๋ณด๋ฉด์„œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์•„์„œ ์ €์™€ ๊ฐ™์€ ๊ณ ๋ฏผ์œผ๋กœ ํž˜๋“  ๋ถ„๋“ค์„ ์œ„ํ•ด ์ œ ์ƒ๊ฐ๋„ ์ •๋ฆฌํ• ๊ฒธ ๊ธ€์„ ์จ๋ด…๋‹ˆ๋‹ค. ์ €๋Š” ๋งฅ OS์—์„œ Xcode๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋”ฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

* ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

 

#include <iostream>
using namespace std;

class CTestData{
public :
    CTestData() {
        cout<<"CTestData()"<<endl;
    }

    ~CTestData(){
        cout<<"~CTestData() : "<<endl;
    }

    CTestData(CTestData &rhs)
    : m_nData(rhs.m_nData)
    {
        cout<<"CTestData(CTestData &)"<<endl;
    }

    CTestData(CTestData &&rhs)
    : m_nData(rhs.m_nData)
    {
        cout<<"CTestData(CTestData &&)"<<endl;
    }
    
    CTestData& operator=(const CTestData &) = default;

   int GetData() const {return m_nData;}
   void SetData(int nParam){m_nData = nParam;}

private :
    int m_nData = 0;
};

CTestData TestFunc(int nParam){
    cout<<"**TestFunc() Begin***"<<endl;
    CTestData a;
    a.SetData(nParam);
    cout<<"**TestFunc() End***"<<endl;
    return a;
}

int main(){
    CTestData b;
    cout<<"*Before*****"<<endl;
    b = TestFunc(20);
    cout<<"*After*****"<<endl;
    CTestData c(b);

    return 0;
}
CTestData()
*Before*****
**TestFunc() Begin***
CTestData()
**TestFunc() End***
CTestData(CTestData &&)
~CTestData()
~CTestData()
*After*****
CTestData(CTestData &)
~CTestData()
~CTestData()

์ฑ…์—์„œ๋Š” ์œ„์˜ ์‹คํ–‰๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค๊ณ  ์ ํ˜€์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ œ๊ฐ€ ์‹คํ–‰์‹œ์ผฐ์„ ๊ฒฝ์šฐ์—๋Š” ์•„๋ž˜ ์‹คํ–‰๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™”์Šต๋‹ˆ๋‹ค.

CTestData()
*Before*****
**TestFunc() Begin***
CTestData()
**TestFunc() End***
~CTestData()
*After*****
CTestData(CTestData &)
~CTestData()
~CTestData()

์™œ ์ด๋™ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜์„๊นŒ์š”?

์ผ๋‹จ, ์ด๋™ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์œ„์น˜๋ถ€ํ„ฐ ์•Œ์•„๋ด…์‹œ๋‹ค. ์ฑ…์—์„œ๋Š” TestFunc์—์„œ return a;๋ฅผ ํ•˜๋Š” ์ˆœ๊ฐ„ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์ž„์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ์™€ ๋™์‹œ์— ์ž„์‹œ ๊ฐ์ฒด์˜ ์ด๋™ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์ฒ˜์Œ์— b = TestFunc(20); ์ฝ”๋“œ์—์„œ ์ž„์‹œ ๊ฐ์ฒด๊ฐ€ b ๊ฐ์ฒด๋กœ ๋Œ€์ž…๋  ๋•Œ ์ด๋™ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์œผ๋กœ ์ฐฉ๊ฐํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋‹น์—ฐํžˆ ๋ง์ด ์•ˆ๋˜๋Š” ๊ฒŒ ์ด๋ฏธ b ๊ฐ์ฒด๋Š” ์œ„์—์„œ ์„ ์–ธํ•˜์˜€์œผ๋‹ˆ ์ด๋ฏธ ์ด ๊ฐ์ฒด๋Š” ๋””ํดํŠธ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์—ฌํŠผ, ๊ทธ๋Ÿผ ์ด์ œ ์ด๋™ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์œ„์น˜๋ฅผ ์•Œ์•˜์œผ๋‹ˆ ์™œ ์ƒ๋žต๋˜์—ˆ๋Š”์ง€๋ฅผ ์•Œ์•„์•ผ๊ฒ ์ฃ . ์ด๋Š” ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ์•Œ๊ฒŒ๋˜์—ˆ๋Š”๋ฐ, '๋ณต์‚ฌ ์ƒ๋žต copy elision'์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด ๋ณต์‚ฌ ์ƒ๋žต์€ ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ์•Œ์•„์„œ ํ•˜๋Š” ์ตœ์ ํ™” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ์—์„œ TestFunc ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด ๋‚ด๋ถ€์—์„œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ๊ฐ์ฒด๋ฅผ returnํ•˜๊ณ  ์žˆ์ง€์š”? ์›๋ž˜๋ผ๋ฉด ์ž„์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ณต์‚ฌ ํ˜น์€ ์ด๋™ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋งž์ง€๋งŒ, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํŒ๋‹จํ•˜๊ธฐ์— ํ•„์š”์—†๋Š” ์—ฐ์‚ฐ์ด๋ผ ์ƒ๊ฐํ•˜์—ฌ NRVO(Named Retrun Value Optimization) ๋ณต์‚ฌ ์ƒ๋žต์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด, ์ž„์‹œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ a ๊ฐ์ฒด ์ž์ฒด๋ฅผ return ํ•ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ณต์‚ฌ ํ˜น์€ ์ด๋™ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค! ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ๋ณต์‚ฌ ์ƒ๋žต ์ตœ์ ํ™”๋ฅผ ๋„๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋‹ค์Œ์ฒ˜๋Ÿผ main ํ•จ์ˆ˜๊ฐ€ ์œ„์น˜ํ•œ cpp ํŒŒ์ผ์„ ๋”๋ธ”ํด๋ฆญํ•˜์—ฌ `-fno-elide-constructors` ๋ฌธ๊ตฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ํ˜น์€ b = TestFunc(20); ์ฝ”๋“œ๋ฅผ `b = std::move(TestFunc(20));` ์œผ๋กœ ๋ฐ”๊ฟ”์ค˜๋„ ๋˜‘๊ฐ™์ด ์ด๋™ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. std::move๋Š” ์˜๋„์ ์œผ๋กœ ์ด๋™ ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ์‹œ์ผœ์ฃผ๋Š” ํ•จ์ˆ˜๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์—ฌํŠผ ์ด๋กœ์จ ์ฑ…๊ณผ ๊ฐ™์€ ์‹คํ–‰๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณต์‚ฌ ์ƒ์„ฑ์ž์™€ ์ด๋™ ์ƒ์„ฑ์ž ๊ด€๋ จํ•˜์—ฌ ์ด ์œ ํŠœ๋ฒ„ ์˜์ƒ์—์„œ ๋„์›€์„ ๋งŽ์ด ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.