본문 바로가기
전문가를 위한 C++

2025/03/15 ch.12 템플릿으로 제네릭 코드 만들기

by 딴짓거리 2025. 3. 16.

C++는 객체지향 프로그래밍 뿐만 아니라 제네릭 프로그래밍도 지원함

재사용 가능한 코드를 작성하는 것이 목적

제네릭 프로그래밍을 지원하기 위한 핵심 요소는 템플릿

 

알고리즘(함수)을 작성할 때 특정한 값에 종속되지 않게 실행되도록 구현한다. 매개변수화

객체 = 데이터와 동작을 하나로 묶은 것

값에 대한 매개변수화를 확장해서 타입에 대해서도 매개변수화할 수 있게 만든것이 템플릿

 

12.2 클래스 템플릿

멤버 변수의 타입, 메서드의 리턴 타입, 메서드의 매개변수 타입등을 매개변수로 받아서 클래스를 정의

주로 객체를 저장하는 컨테이너나 데이터 구조에서 많이 사용함.

클래스가 특정한 타입에 종속되지 않게 만들 수 있다.

클라이언트는 이런 템플릿을 이용하여 저마다 원하는 타입에 맞게 클래스를 인스턴스화해서 사용할 수 있다.<- 제네릭 프로그래밍

장점 - 타입안정성. 메서드를 비롯한 멤버의 타입을 모두 구체적으로 정의할 수 있음

 

뭔..소리여..

const unique_ptr<GamePiece>& GameBoard::at(size_t x, size_t y) const
{
	verifyCoordinate(x, y);
	return m_cells[x][y];
}
unique_ptr<GamePiece>& GameBoard::at(size_t x, size_t y)
{
	return const_cast<unique_ptr<GamePiece>&>(as_const(*this).at(x, y));
}

const 버전 함수와 비const버전 함수를 지원하려면 같은 내용을 두번 써줘야할것이다

그런데 코드중복을 피하기 위해 무슨짓을 했는지 보자

 

const unique_ptr<GamePiece>& GameBoard::at(size_t x, size_t y) const
{
	verifyCoordinate(x, y);
	return m_cells[x][y];
}

먼저 const 버전의 함수를 온전히 구현했다

 

unique_ptr<GamePiece>& GameBoard::at(size_t x, size_t y)

비const 버전의 함수를 만드는 것은?

 

as_const(*this).at(x, y)

as_const를 이용해 강제로 const 버전 함수를 호출한다

return const_cast<unique_ptr<GamePiece>&>(as_const(*this).at(x, y));

그럼 const를 반환하잖아? 그러니 const_cast로 풀어주고 반환한다

 

결과적으로 구현은 const 버전함수 하나만 했고

비 const 버전은 const 버전을 호출한후 const를 풀어서 반환하는 식으로 구현했다

스콧 메이어씨..

 

 

클래스를 범용성있게 구현하려고 상속등등을 이용해도 좋지만 한계가 명확하다.
여러 타입의 객체를 저장하게 하려고 값을 항상 포인터로 받아야 하며, 다운캐스트를 해야 기능을 사용할 수 있는등 타입 안정성이 떨어진다.

또한 이런 꼼수로는 베이스 클래스를 상속한 타입만 지원하고 기본타입은 사용할 수 없다

 

그래서 클래스 템플릿을 이용하여 제네릭 클래스를 만들면 좋다

 

클래스 템플릿을 이용하면 클래스가 특정한 타입에 종속되지 않게 만들 수 있다.

이런 템플릿을 이용하면 저마다 원하는 타입에 맞게 클래스를 인스턴스화해서 사용할 수 있다.

제네릭 프로그래밍

 

다형성을 이용하면 추상 베이스 클래스를 이용해야 하지만 클래스 템플릿을 활용하면 클래스 안에 있는 메서드를 비롯한 멤버의 타입을 모두 구체적으로 정의할 수 있다.

 

 

~628p