캐스팅 연산자
const_cast
int iNumber = 10;
const int* p = &iNumber;
int* pTemp = const_cast<int*>(p);
*pTemp = 20;
cout << iNumber << endl; //20
const를 가진 자료형의 const 속성을 일시적으로 제거한 연산자이다.
포인터 또는 레퍼런스일때만 const제거가 가능하다.
reinterpret_cast
int iNumber = 65;
char* pName = reinterpret_cast<char*>(&iNumber);
cout << pName << endl; //A
const 포인터를 제외한 모든 포인터의 형 변환을 허용한다.
비논리적인 형 변환도 허용하기 때문에 위험하고 사용을 지양하는 편이다.
인라인 함수 vs 매크로 함수
#define SQUARE(x) x * x // 매크로 함수
inline int Square(int x) // 인라인 함수
{
return x * x;
}
인라인 함수는 매크로 함수와 비슷하다. 둘 다 함수 호출을 처리하지 않고 함수 코드를 호출 지점에 삽입한다.
하지만 인라인 함수는 함수 호출을 줄이기 위해 함수의 본문을 호출하는 곳에 삽입하는 반면
매크로 함수는 전처리기가 함수 코드를 치환한다. 말이 비슷해보이는데 뭐가 다른 걸까?
3 + 1 * 3 + 1 // 7 : 매크로 함수
(3 + 1) * (3 + 1) // 16 : 인라인 함수
square(3+1)을 했을 때 우리가 의도한 결과는 아마 16일 것이다. 하지만 매크로 함수는 적어놓은 코드를 그대로
작성했기 때문에 7이라는 결과가 나왔고 인라인 함수는 그 자리에서 함수를 실행한듯 한 효과를 낸다.
매크로 함수의 x에 괄호를 붙이면 16이 나오긴 하지만 무식한 전처리기가 알아들을 수 있도록 변수마다 괄호를 붙여줘야 하고 컴파일러에서 오류를 확인할 수 없어 디버그에 어려움이 있다.
인라인 함수와 매크로 함수는 너무 길게 작성하거나 과도하게 많이 사용하면 코드 크기가 증가하고 컴파일 시간 또한
증가시키기 때문에 적당히 조절해야 한다. 또한 인라인 함수는 스택프레임 생성 같은 건 없지만 인자전달은 하기 때문에 많이 호출할 수록 함수 호출 오버헤드가 증가할 수 있다. 인라인 함수는 코드가 짧으면 inline 키워드를 안붙이더라도 자동으로 인라인 함수로 컴파일러가 처리한다. 또한 클래스 선언부(헤더파일)에 멤버 함수의 몸체까지 작성하면 역시 인라인 함수로 처리한다.
연산자 오버로딩
함수 오버로딩 규칙을 연산자에 적용한 문법이다.
연산자 오버로딩은 좌측 객체를 기준으로 수행한다.
A+B
A.+(B)
+연산자에 대한 오버로딩은 A의 멤버함수, 이름이 +이고 매개변수로 B를 받는 함수 오버로딩과 같다.
const CObj operator + (const CObj& rObj) const
{
CObj Temp(m_iX + rObj.m_iX, m_iY + rObj.m_iY);
return Temp;
}
int형 변수 m_iX와 m_iY를 가지고 있는 클래스 CObj의 +연산자 오버로딩이다.
매개변수는 복사본을 생성하지 않기 위해 레퍼런스로 받고 지역 객체를 생성하여 그 안에 변수들을 더한 값으로
생성자를 호출해 m_iX, m_iY에 값이 더해진 객체를 반환한다. 임시 객체를 반환하기 때문에 레퍼런스로 반환할 수 없다.
그리고 임시객체를 수정하는 것은 의미 없는 일이기 때문에 리턴타입에 const를 붙여주고 피연산자도 보통 읽기만 하므로
const를 붙여준다. 덧셈 뺄셈 곱셈 등 이항 연산자 경우 객체의 값을 읽기만 하므로 함수에도 const를 붙여준다.
대입 연산자, 증감 연산자 등 객체의 값을 수정하는 연산자의 경우 const를 붙이면 안된다.
const CObj operator+(const int iData,const CObj& rObj) const
{
CObj Test(rObj + iData);
return Test;
}
연산자 오버로딩으로 매개변수 두개를 받아 30 + obj 같은 연산을 진행할 수도 있다. 이 경우
임시객체의 생성자 매개변수로 CObj객체와 int형 변수를 더하고 있으므로 이것에 대한 연산자 오버로딩이 선행해서 필요하다. +는 이렇게 기본형과 연산이 가능하지만 =,(),[],->는 클래스 멤버로만 연산이 가능하다. 그리고 이것들은
좌측 기준으로만 연산자 오버로딩을 수행한다.
'Today I Learned' 카테고리의 다른 글
| 23.02.22 - 템플릿2, STL개론 (0) | 2023.02.22 |
|---|---|
| 23.02.21 - 함수 객체, 임시 객체, 템플릿 (0) | 2023.02.21 |
| 23.02.17 - 순수 가상 함수, 가상 소멸자, 캐스팅 연산자 (0) | 2023.02.17 |
| 23.02.16 - 정적 바인딩과 동적 바인딩, 가상 함수 (0) | 2023.02.16 |
| 23.02.15 - extern, friend, 상속성 (0) | 2023.02.15 |