본문 바로가기

C++

[C++] const string&을 쓰는 이유(const와 레퍼런스)

private:
	string m_strTag;
public:
	void SetTag(const string& strTag)
	{
		m_strTag = strTag;
	}

 

위 코드는 m_strTag 를 지정하는 함수이다. 그런데 string이 아니라 const string&을 사용하는 이유가 궁금해서 찾아보았다. 우선 레퍼런스를 사용하는 이유는 Call by Reference를 이용해서 값을 복사하지 않아 메모리 낭비를 줄이고 속도가 더 빠르기 때문이다. 그렇다면 const는 왜 붙이는 것일까? 

 

#include <iostream>
#include <string>
using std::string;

string g_value;

void ProcessStringByRef(string& s) {
    g_value = s;
    std::cout << g_value << "\n";
}

void ProcessStringByRef2(const string& s) {
    g_value = s;
    std::cout << g_value << "\n";
}

int main() {
    g_value = "red";
   // ProcessStringByRef("blue"); error
    ProcessStringByRef2("blue");
}

위 코드에서 첫번째 함수의 인수로 "blue"를 집어넣으면 에러가 발생한다. 왜냐하면 "blue"는 string이 아니기 때문에 컴파일러가 "blue"와 레퍼런스 s를 바인딩하는데, C++에서는 임시 레퍼런스와 비상수(non-const) 레퍼런스를 바인딩할 수 없다는 규칙이 있기 때문이다. 

 

인수로 레퍼런스를 넣는 경우와 const 레퍼런스를 넣는 경우가 헷갈려 첨부한다. 레퍼런스는 좌변값(lvalue)을 받아 초기화되고나면 그 후로 별명처럼 쓰이며 연산이 가능하다. 연산 또한 대상체에 대한 연산으로 간주한다. 그래서 위 코드에서 n이 x에 대한 별명으로 설정한 다음 n = n + 10 같은 연산이 가능한 것이다. 레퍼런스는 좌변값(lvalue), 우변값(rvalue) 둘 다 가능하다. const 레퍼런스도 연산은 가능하지만 좌변에 위치한 연산은 불가능하다. const 레퍼런스는 우변값(rvalue)만 가능하다.

 

int a;

void DoWork(const int &n)
{
    a = n * 2;  // If n was a reference to a, n will have been doubled 

    f();  // Might change the value of whatever n refers to 
}

int main()
{
    DoWork(a);
}

const 레퍼런스도 위와 같이 a값을 바꿀 수 있다. 그러나 우변값(rvalue)으로만 이용이 가능하다.

'C++' 카테고리의 다른 글

[C++] vector, list, map에 할당한 메모리 해제  (0) 2022.01.20
[C++] 상속관계에서 복사 생성자 호출  (0) 2022.01.18
[C++] static 멤버와 싱글톤 패턴  (0) 2022.01.17
[C++] 맵(map)  (0) 2022.01.11
[C++] 셋(set)  (0) 2022.01.11