참조자 형식

참조자 형식은 겉으로 보기엔 포인터와 다르지만 본질은 C언어의 포인터와 비슷하다. 

사용법은 "형식 &이름 = 원본"과 같이 반드시 선언과 동시에 초기화를 해줘야한다.

 

아래와 같이 nData의 참조자인 ref 변수를 만들었다. 그리고 메모리에서 &nData와 &ref를 둘다 까봤다.

결과는 008FFE2C로 둘다 같은 메모리 주소를 가지는 것 처럼 나온다. 그러니 ref변수에서 값을 20으로 바꾸면 원본인 nData의 값도 바뀌게 된다. 마치 포인터를 쓰는것과 같다.

	int nData = 10;
	int& ref = nData;

	ref = 20;
	cout << nData << endl;

	int* pData = &nData;
	*pData = 30;
	cout << nData << endl;

ref와 nData는 같은 주소

 

 

참조에 의한 호출, 주소에 의한 호출 예제
#include <iostream>
#include <string.h>
using namespace std;

class CIntArray
{
public:
	CIntArray(int nSize)
	{
		m_pnData = new int[nSize];
		memset(m_pnData, 0, sizeof(int) * nSize);
	}
	
	~CIntArray()
	{
		delete m_pnData;
	}
	
	int& operator[](int nIndex)
	{
		cout << "operator[]" << endl;
		return m_pnData[nIndex];
	}

private:
	int* m_pnData;
	int m_nSize;
};

int main()
{
	CIntArray arr(5);
	for (int i = 0; i < 5; ++i)
	{
		arr[i] = i * 10;
		cout << arr[i] << endl;
	}

	return 0;
}

 

CIntArray는 nSize 크기 만큼 int array를 만드는 클래스다(동적할당)

주목해야 할 점은 int& operator[](int nIndex)다.

여기서 int&는 참조형을 반환 하는데 무엇에 대한 참조형일까?

m_pnData 포인터의 요소 즉 int에 대한 참조형이다. 왜냐하면 m_pnData가 포인터인데 연속된 int형을 가르키는 포인터니깐!

 

여기서 참조를 빼면 "식이 수정할 수 있는 lvalue여야 합니다" 라는 에러가 난다.  이게 무슨 뜻일까?

nIndex가 0이라고 가정하면 m_pnData[0]에 해당하는 주소값(참조)을 넘겨야 그 주소값에 i * 10 값을 넣는데 &(참조)를 빼면 m_pnData[0]의 값을 return 하니 위와 같은 에러가 뜬다. 

참조는 곧 포인터라 했다 참조를 포인터로 고치는건 아주 간단한다.

 

참조에서 포인터로 변경
#include <iostream>
#include <string.h>
using namespace std;

class CIntArray
{
public:
	CIntArray(int nSize)
	{
		m_pnData = new int[nSize];
		memset(m_pnData, 0, sizeof(int) * nSize);
	}
	
	~CIntArray()
	{
		delete m_pnData;
	}
	
	int operator[](int nIndex) const
	{
		cout << "const" << endl;
		return m_pnData[nIndex];
	}
	
	int* operator[](int nIndex)
	{
		cout << "operator[]" << endl;
		return &m_pnData[nIndex];
	}

private:
	int* m_pnData;
	int m_nSize;
};

int main()
{
	CIntArray arr(5);
	for (int i = 0; i < 5; ++i)
	{
		*(arr[i]) = i * 10;
		cout << *(arr[i]) << endl;
	}

	return 0;
}

1. int& operator[]를 int*로 바꿨다.

2. return 할때 값이 아니라 주소로 바꿨다(&m_pnData[nIndex])

3. 대입할 때 *(arr[i])로 변경했다.

 

결론 : 참조는 포인터다.

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

C++ 깊은복사 얕은복사  (0) 2020.02.02
C++ 복사 생성자(참조형 파라미터)  (0) 2020.02.01
C++ this 포인터  (0) 2020.02.01
C에서 C++ 객체지향의 변환 과정  (0) 2020.01.28
C++ new 메모리 동적할당  (0) 2020.01.27

+ Recent posts