C++
[강의] 11월 15일 수업정리
k-codestudy
2024. 11. 17. 19:02
어제 배운것에 대한 복습과 만들어주는 상속에 대한 수업을 들었다.
1. 복습
1.1 enum의 핵심 개념
- 숫자에 의미를 부여하는 것이 가장 중요하며, 숫자와 의미의 관계는 두 가지로 나뉜다:
- 의미가 중요한 경우
- 예: 고유 ID처럼 서로를 구별하기 위한 목적.
- 숫자가 중요한 경우
- 예: π 값을 3으로 고정할 때처럼 값 자체가 중요한 경우.
- 의미가 중요한 경우
하지만 대부분의 경우, 구별을 목적으로 사용을 한다.
1.2 enum 사용의 장점
- #define 대신 enum 사용
- #define은 단순히 상수를 정의하는 데 그친다.
- enum은 명확한 자료형을 제공하므로 의미와 타입이 더 분명하다.
- 코드를 처음 접하는 상황에서도 무엇을 넣어야 할지 명확하게 알 수 있다.
- 소속 관계
- #define은 소속 관계를 표현할 수 없지만, enum은 소속 관계를 나타낼 수 있다.
- 예: 특정 enum 값들이 하나의 그룹(열거형)에 소속됨을 명확히 알 수 있다.
- #define은 소속 관계를 표현할 수 없지만, enum은 소속 관계를 나타낼 수 있다.
- 고유 ID 부여
- 서로 다른 값들 간의 구분을 위해 enum을 사용하면 직관적이다.
1.3 C++의 enum과 enum class의 차이점
- 기본 enum의 단점
- 독립적으로 사용할 수 있다 보니 소속 관계가 뚫려 있는 경우가 생긴다.
- 자동으로 int로 변환되며, 다른 자료형에서도 자유롭게 사용 가능해 타입 안전성이 부족하다.
- enum class의 장점
- 소속 관계가 명확하다.
- 다른 자료형과 섞이는 일이 없어 타입 안전성을 보장한다.
- 다른 자료형과 섞이는 일이 없어 타입 안전성을 보장한다.
- 소속 관계가 명확하다.
1.4 초기화와 enum 사용 시 유의점
- 초기화 상태 보장
- C++에서 변수를 유니폼 초기화하면 기본값 0이 들어가지만, 해당 값이 반드시 유효한 값일지는 보장되지 않는다.
- 따라서 초기값을 명확히 설정하는 것이 좋다.
- 예: "데이터를 아직 다루지 않았다"는 것을 나타내기 위해 디폴트 값으로 0을 설정.
- 디폴트 리소스 설정의 중요성
- 명확한 초기값을 통해 코드의 안정성과 가독성을 높인다.
1.5 결론
- enum은 의미를 부여하고 구별하기 위해 사용한다.
- C++에서는 타입 안전성과 명확한 소속 관계를 위해 enum class를 사용하는 것이 권장된다.
- 초기화와 디폴트 값을 통해 데이터를 다루지 않은 상태를 명확히 표현하고, 안정적인 코드를 작성하는 것이 좋다.
2. 만들어주는 상속
// moveMGR.h
#pragma once
#include <stdio.h>
#include "move.h"
class C_MOVEMGR
{
public:
enum class E_TYPE
{
E_NONE = 0,
E_WALK,
E_FLY,
E_SWIM,
E_MAX
};
public:
C_MOVEMGR() = default;
C_MOVE* createMove(E_TYPE eType);
void deleteMove(C_MOVE* pMove);
};
// move.h
#pragma once
#include <stdio.h>
class C_MOVE abstract
{
public:
C_MOVE() = default;
virtual ~C_MOVE() = default;
virtual void move() abstract;
};
class C_WALK : public C_MOVE
{
public:
void move() override;
};
class C_FLY : public C_MOVE
{
public:
void move() override;
};
class C_SWIM : public C_MOVE
{
public:
void move() override;
};
// moveMGR.cpp
#include "moveMGR.h"
C_MOVE* C_MOVEMGR::createMove(E_TYPE eType)
{
C_MOVE* pMove{};
if (eType == E_TYPE::E_WALK)
pMove = new C_WALK{};
if (eType == E_TYPE::E_FLY)
pMove = new C_FLY{};
if (eType == E_TYPE::E_SWIM)
pMove = new C_SWIM{};
return pMove;
}
void C_MOVEMGR::deleteMove(C_MOVE* pMove)
{
delete pMove;
pMove = nullptr;
}
// move.cpp
#include "move.h"
void C_WALK::move()
{
printf("걷다\n");
}
void C_FLY::move()
{
printf("날다\n");
}
void C_SWIM::move()
{
printf("수영하다\n");
}
// main.cpp
#include <iostream>
#include "moveMGR.h"
int main()
{
C_MOVE* pMove{};
C_MOVEMGR cMgr{};
pMove = cMgr.createMove(C_MOVEMGR::E_TYPE::E_FLY);
pMove->move();
pMove = cMgr.createMove(C_MOVEMGR::E_TYPE::E_SWIM);
pMove->move();
pMove = cMgr.createMove(C_MOVEMGR::E_TYPE::E_WALK);
pMove->move();
cMgr.deleteMove(pMove);
}