template와 class에 대한 얘기(1)

2021. 11. 23. 23:14c,c++ 기본/next step

320x100

안녕하세요 대학생 개발자입니다.

 

이번글에서는 template에 대해서 정리를 해보려고합니다.

우선 템플릿에 대해서 얘기하기 전에 우리가 c언어에서 부터 지금까지 모든 타입이라는 개념을 어떻게 해왔는지를 간단히 정리해보도록하겠습니다.

똑같은 기능을 변수 타입만 바꼈을때 똑같이 쓰는방법... c언어에서는 당연 다른 함수를 만들어야됬습니다.

int add(int a, int b);
float add(float a, float b);

이런 오버로딩의 개념은 c언어에서는 지원하지 않으니까요...

c언어에서는 안타깝게도 이런방식을 써왔었습니다.

int addInt(int a, int b);
float addFloat(float a, float b);

그리고 c++에서는 이를 조금 보안해서 오버로딩이라는 개념을 지원했었습니다.

int add(int a, int b);
float add(float a, float b);

이제는 위와같은 코드가 가능해지죠...

하지만 이것도 불편합니다. 왜냐면 각 타입마다 모든것을 내가 구현해야되니까요...

 

그럼 우리는 이런식으로 코드를 짤 수 있습니다.

template<typename T>
T add(T a, T b);

이 함수 하나면 모든 더하기 연산은 다 가능해집니다. 물론 그 T type에 대한 + 연산이 있어야 되겠지만요 그건 추후에 생각해 보자구요.

 

자 여기까지가 아마 c++의 기본을 배우신 분들이라면 모두 아실겁니다.

그리고 게임서버에서는 템플릿이 크게 필요가 없습니다. (사용하는 케이스말고 만드는 케이스)

템플릿이 최대 효율을 발휘하는 곳은 자료구조 부분이니까요.

 

사실 게임이라고 하면 정해진 규칙 정해진 행동 정해진 아이템 정해진 무언가에 따라서 흐르게 되있습니다.

이것만 놓고 본다고 해도 모든 타입에 열려있는 템플릿의 필요성이 크게 느껴지지 않을겁니다.

 

템플릿이 자료구조에 많이 쓰이는 이유는 뭐... 충분히 추론 가능하실거라고 생각합니다.

당연하게도 자료구조는 각 타입의 자료들을 보관하기위한 용도로 만들어지는 거기떄문에... 모든 타입에 열려있어야됩니다. 그래서 자료구조에서 템플릿을 많이 사용하는거구요...

 

템플릿 얘기는 여기까지만 하겠습니다. 왜냐면... 템플릿을 이용한 무언가를 구현하는 경우는 그렇게 많이 있지는 않을거거든요...

 

 

그럼 c++의 꽃인 클래스에 대한 정리를 좀 해보겠습니다.

 

함수중심적이고 절차지향적인 프로그래밍에서는 모든것은 데이터와 기능으로 구분이 되어있었습니다.

물론 c++에 클래스또한 세세하게 따져보면 그렇게 되어있습니다.

 

하지만 하나의 덩어리로 본다면 하나의 객체가 자기가 할 수 있는 행동을 스스로 수행한다는 점에서 그것은 데이터와 기능이 하나로 합쳐져있는 것이라고 볼 수 있겠죠.

 

일단 클래스 자체에 대해서는 논하지 않을겁니다.

아마 이 글을 읽어오시면서 다 이해하셨던 분이라면 클래스에 대해서 모를리가 없는분이기 때문입니다.

 

사실 클래스를 얘기하는 이유는 객체지향에 대해서 조금 얘기해보고 싶기 때문입니다.

우리가 클래스를 처음 배울때 Encapsulation이라는 용어를 듣게될겁니다. 캡슐화죠.

 

L2의 frame header를 보고도 Encapsulation이라고 부르는데 내용을 감싸서 내부를 가려버리기 때문입니다.

그리고 나서 배우는게 Getter와 Setter입니다.

잠시 다른길로 셀거같긴한데 저는 개인적으로 Getter와 Setter의 존재가 객체지향의 파괴라고 생각하고있어서...

class CPlayer;
CPlayer* Player =...;


Player->SetPosition(Player->GetXPosition(),Player->GetYPosition());

Player->Move(Player::Direction::Left);

위 문장이랑 아랫문장중 뭐가더 객체지향이라고 보십니까...

저는 당연히 아래쪽이라고 생각하는데 사실 Getter와 Setter전부다가 문제인 것은 아닙니다.

클래스를 조금만 바꿔보면 Getter와 Setter의 필요성도 있긴합니다.

 

그래서 제가 여기서 잠시 길을 세면서까지 이얘기를 하는것은 클래스의 목적에 맞게 설계를 해야된다는겁니다.

클래스의 멤버변수를 public으로 오픈하는것이나 클래스의 private변수를 게터와 세터로 직접 바로 값을 바꿔버리는 함수를 만드는것... 둘은 동일한 개념이죠... 사실보면 굳이 코드낭비하지 말고 그런경우엔 그냥 퍼블릭으로 열어버리세요... 물론 이행동을 하기전에 퍼블릭으로 만들어도 되는지부터 확인해보시고...

너무 당연한말인가요..? 근데 직접해보십쇼... 게터와 세터의 사용이 저절로 나오게될겁니다.

 

네 그래서 원래대로 다시 돌아가보겠습니다.

 

생성자와 소멸자에 대한 얘기를 해보겠습니다.

아마 대부분 c++을 배울때 생성자와 소멸자를 따로 만들어주지 않으면 default생성자가 생성된다 라고 배우셨을겁니다.

과연 그게 맞을까요?... 네 맞습니다 일단은 당장 생성자가 생기긴 합니다. 하지만 하는 행동이 존재하지 않기때문에 최적화를 켜놓으면 버퍼만 잡아놓고 아무행동을 하지 않는다는 점입니다.

 

물론 상속관계에서 부모의 생성자가 있고 자식의 생성자가 없으면 부모의 생성자를 호출해야되기때문에 자식의 생성자가 생기긴합니다만... 이런경우가 아니라면 그냥 아무런 행동도 하지 않습니다.

 

생성자와 소멸자에선 중요한 포인트가 있습니다.

생성자와 소멸자에는 로직에 매우 자유로워야 합니다.

뭐 예를들어 A라는 클래스의 전역객체는 B라는 클래스의 전역객체를 생성자에서 사용하게되고

B라는 클래스의 전역객체는 생성자에서 A클래스의 전역객체를 사용한다고하면...

이는 누가 보장을 해주지 않습니다

A의 생성자가 먼저 호출되면 B는아직 초기화 되지 않았기때문에 사용에 문제가 있을것이고 반대의 경우에도 문제가 생길겁니다.

물론 visual studio의 경우 ms에서 같은 소스라면 선언되어있는 라인의 순서대로 생성자가 호출되고 반대로 소멸자는 그 반대순서로 호출된다고 명시하고 있긴합니다만... 이는 ms의 메뉴얼이고 실제 c++의 규격이 아니기 때문에 이렇게 생각하고 계시면 안됩니다. 추가로 다른 소스라면 진짜로 알수없기 때문입니다. 어떤소스가 먼저 컴파일되냐에 따라서 달라지는거니까요...

 

아마 제가 예전에 이런말을 적은적이 있는것 같은데요...

변수를 선언할때 디버깅을 위해서 스코프 밖으로 빼버려라는 말을 했었던 적이있습니다.

기본 타입의 변수라면 이 말에 해당됩니다. 왜냐면 스코프 밖에있어도 안에있어도 그냥 공간할당후 끝이거든요... 근데 스코프를 빠져나가버리면 vs의 조사식에도 안나오고... 그러면 메모리를 보기도 까다로워 지기 때문입니다.

 

하지만 클래스의 경우에는 조금 다른데요... 두가지 케이스가 있습니다. 생성자의 유무 여부입니다.

클래스도 결국 버퍼덩어리입니다. 그냥 스택에 빈공간 만들어놓고 거기를 그냥 쓰는겁니다. 구조체와 동일한거죠.

생성자가 존재하지 않는다면 여기까지가 끝입니다.

만일 생성자가 존재한다면 대신에 초기화때 생성자라는 로직이 들어가게됩니다. 당연히 call을 할것이고 아주 약간이지만 시간을 소비할겁니다.

만약 분기문 내부에서만 클래스의 객체가 필요하다면... 그 분기문에 들어가지 않는다면 객체의 생성자를 호출 안되게 하는 것이 효율적이겠죠... 물론 생성자가 있을경우입니다.

없을경우에는 일반 변수와 다르지 않습니다.

 

음... 다음으로 멤버함수에 대해서 얘기를 해야되는데요 사실 멤버함수에 좀 중요한 부분이 많습니다.

그리고 내용도 꽤나 길어질 것 같습니다.

네... 여기서 끊고 내용을 다음글에서 이어서 적으려는 밑밥깔기입니다.........

 

오늘도 긴글 읽어주셔서 감사합니다...

갑자기 훅 끊어버리게 되어서 죄송합니다... 글이 너무 길어지는건 둘째고 너무 늦은 밤이기 때문에 그런것 같습니다...

그럼 다음에 더 좋은 정보로 찾아오도록하겠습니다

안녕히계세요

 

320x100

'c,c++ 기본 > next step' 카테고리의 다른 글

상속에 대한 얘기  (0) 2021.11.24
class에 대한 얘기(2)  (0) 2021.11.24
new와 delete에 대한 얘기  (0) 2021.11.20
메모리와 c++에 관한 얘기  (0) 2021.11.14
DLL,LIB, FILEIO에 대한얘기  (0) 2021.11.13