참조자 형식
참조자 형식은 겉으로 보기엔 포인터와 다르지만 본질은 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;
참조에 의한 호출, 주소에 의한 호출 예제
#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 |