[Effective C++] 낌새만 보이면 const를 들이대 보자!

char str[] = "Hello, World!";

1. char* ptr = str;		// 포인터 조작 가능, 데이터 조작 가능
2. const char* ptr = str;	// 포인터 조작 가능, 데이터 조작 불가능
3. char* const ptr = str;	// 포인터 조작 불가능, 데이터 조작 가능
4. const char* const ptr = str;	// 포인터 조작 불가능, 데이터 조작 불가능

1. const를 붙여 선언하면 컴파일러가 사용상의 에러를 잡아내는 데 도움을 줍니다. const는 어떤 유효범위에 있는 객체에도 붙을 수 있으며, 함수 매개변수 및 반환 타입에도 붙을 수 있으며, 멤버 함수에도 붙을 수 있습니다.

class Transform
{
...
public:  **const** float3& getDirection(void) **const** { return(_direction); }
...
}

const float3& dir = transform->getDirection();	// _direction의 상수 참조
dir.y = 0.0f;					// Compilation error

float3& dir = pTransform->getDirection();	// Compilation error

float3 dir = pTransform->getDirection();		// _direction의 복사
dir.y = 0.0f;

1) 상수 객체를 반환한다면 함수도 const 키워드를 붙여준다.
class Transform
{
...
public: void setDirection(**const** float3& direction)
	{
	    direction.y = 0.0f;		// Compilation error
	    _direction = direction;
	}
...
}

2) 인자로 받은 값을 함수 내부에서 조작할 일이 없다면 const 키워드를 붙여준다.

2. 컴파일러 쪽에서 보면 비트수준 상수성을 지켜야 하지만, 여러분은 개념적인(논리적인) 상수성을 사용해서 프로그래밍해야 합니다.

class TextBlock
{
...
public:	char& operator[](size_t offset) **const**
	{
	    return(pText[offset]);
	}
    
private: char* pText;
}

부적절하지만 비트수준 상수성이 있어서 허용되는 operator[]의 선언.
const 함수임에도 불구하고 상수 참조자가 아닌 참조자 반환을 한다.
pText는 안 건드린다는 점은 확실하기 때문에 컴파일 에러가 나지 않는다.

const TextBlock tb("Hello");
char* pCh = &tb[0];
*pCh = 'J';

위 코드를 수행하면 상수객체인 tb가 "Jello" 문자열을 갖게 된다.

3. 상수 멤버 및 비상수 멤버 함수가 기능적으로 서로 똑같게 구현되어 있을 경우에는 코드 중복을 피하는 것이 좋은데, 이때 비상수 버전이 상수 버전을 호출하도록 만드세요.

1. 중복코드o
class Transform
{
public:	const float3& getDirection(void) const
	{
	    ...
	    return(_direction);
	}
public:	float3& getDirection(void)
	{
	    ...
	    return(_direction);
	}
    
private: float3 _direction;
}

2. 중복코드x
class Transform
{
public:	const float3& getDirection(void) const
	{
	    ...
	    return(_direction);
	}
public:	float3& getDirection(void)
	{
	    return(const_cast<float3&>(getDirection()));
	}
    
private: float3 _direction;
}

getDirection() 함수에서 _direction을 반환하기 전에 내부적으로 추가 구문을 수행한다면
중복 코드를 작성하게 되는데, 비상수 버전이 상수 버전 함수를 호출하고,
const_cast를 활용하면 중복 코드를 피할 수 있다.

좋은 웹페이지 즐겨찾기