2026-03-07(토)

조범근·2026년 3월 7일

TIL

목록 보기
12/25

주말에 시간 내서 이해하려 하니까 운동 많이된다. 자기 전에 생각 날듯.

구현한 것

int main(){
    int i;
    vector<unique_ptr<Player>> p_ptr;

    p_ptr.push_back(make_unique<Warrior>());
    p_ptr.push_back(make_unique<Magician>());
    p_ptr.push_back(make_unique<Thief>());
    p_ptr.push_back(make_unique<Archer>());
    
    cout << " * 번호를 입력하면 해당 직업에 맞춰 공격을 합니다.\n";
    cout << "1. 전사 / 2. 마법사 / 3. 도적 / 4. 궁수\n";

    cin >> i;

    p_ptr[i - 1]->attack();
} 

어제 이해한대로 모르면 일단 동적배열로 포인터를 선언해라!!


헤더파일과 소스파일로 나눠서 해본건 처음이였다. 어떻게 나누냐면

헤더파일(.h) -> 간단한 클래스 선언, 멤버 변수, 함수 선언

소스파일(.cpp) -> 함수 내용 작성, 생성자, 소멸자 내용 작성

근데 이렇게 코딩 하다보니까 의문점이 들었다.
Monster.hPlayer.h를 include 해야하고 Player.hMonster.h를 include 해야하는데 ?

Q. 헤더파일간 이렇게 순환 참조가 되면 어떡하나요..?

A. 순환 참조가 일어나면 !!

  1. 컴파일러가 Player.h를 읽기 시작합니다.

  2. 첫 줄에 #include "Monster.h"를 보고 Monster.h로 점프합니다.

  3. Monster.h 첫 줄에 #include "Player.h"가 있네요? 다시 Player.h로 점프합니다.

  4. Player.h에 가니 또 Monster.h로 가라고 합니다.

  5. 무한 반복


    그럼 어케함
    Player.h를 참조 하는 것은 직업으로만 한다. Monster.h#include "Player.h" 는 하지말고 전방 선언을 한다. 전방선언은 class (헤더파일 이름);으로 선언 가능하고 쓰면 어떻게 되냐

    " 일단 Player.h가 있다고 생각하고 진행 해 주세요 ~ 나중에 처리할게요 ~"

    결국 이렇게 되면 나중에 어디서 갚냐?? 바로 Monster.h를 참조하는 Monster.cpp에서 #include "Player.h"를 해주는 거임. 이것도 막 쓸 순 없을 것 같은데 언제 쓰면 좋을까

  • 포인터나 참조형만 쓸 때 : Player*, Player&, unique_ptr<Player>, shared_ptr<Player>

  • 함수의 매개변수나 리턴 타입으로 등장할 때 : void Attack(Player* target); 처럼 선언만 할때

  • 상호 참조가 발생할 때 : PlayerMonster처럼 서로가 서로를 알아야 하는 관계일때

    나중에 다 갚는다고




Q. Getter와 Setter가 왜 필요한가요?? 값 그냥 가져오면 되는거 아님?

A. 이론으로만 배울때, 이게 왜 필요하지 생각해었다. 근데 직접 해보니까 알겠음.

hp > 0 는 조건이 있는데 그냥 this->HP += -10000; 이런식으로 해버리면 답이 없기 때문.
또, 다른 클래스에서 참조할때 값을 변경할 수 없어서 이용



Q. 삼항연산자와 cout을 같이 쓰고 싶은데 ?에 빨간줄이 쳐져요 어캄?

A. 조건 ? true : flase 조건이 true 면 왼쪽 false면 오른쪽이 삼항연산자

std::cout << damage < 0 ? 1 : damage << std::endl;

이렇게 되면 삼항연산자인 ? 보다 <<가 연산순위가 낮기 때문에

std::cout << (damage < 0 ? 1 : damage) << std::endl;

괄호를 쳐줘야함. 삼항연산자는 값만 반환하는게 바람직 하다고 함.




Q. #prgma once 가 먼가요

A. #prgma once 헤더가드

이게 없으면 main.cpp에서 Warrior.hMagician.h를 둘 다 불러올 때, 기본클래스인 Player.h가 두 번 읽혀 클래스 중복 정의 에러가 난다.



Q. 왜 자꾸 매개변수 nickname을 받나요 다른 직업으로 전직하면 필요없어 지는거 아닌가요?

A. Warrior 파생 클래스 에서 nickname을 바꿀 필요가 없더라도 어떤 이름의 플레이어가 전사가 되었는지를 기본 클래스에게 알려줘야 하기 때문이다. 파생 클래스에서 사용하는게 아니라 기본 클래스를 지나다니기 위한 통행료라고 생각하면 된다.



Q&A


Q1. int (&arr)[N] 굳이 괄호에 넣는 이유가 뭘까요??

A.
int arr[3] -> 포인터 3개를 가진 배열
int (
arr)[3] -> 크기 3인 배열을 가리키는 포인터
int &arr[3] -> 참조자 3개를 가진 배열 불가능 (에러)
int (&arr)[3] -> 크기 3인 배열을 가리키는 참조자 가능

int &arr[N]은 실행도 안됨



Q2. template은 using namespace std; 처럼 선언해놓는게 아닌가요?

A. template <typename T>

바로 다음에 오는 정의에만 적용 된다. main은 T의 자료형을 정해줘야 하기 때문에 불가능



Q3. Class에서 private는 안 적어도 되나요??

A.

class Array {
T data[100];
int size;    // private
public:     

C++의 class는 접근 제어자를 명시하지 않을 경우 기본적으로 private로 설정됨.



Q4. void Player::printPlayerStatus()에서 :: 이게 뭔가요?

A. .h 헤더파일에서 .cpp에 옮겨와서 적을때 선언만 해둔 함수를 적는 거임

// Player .h 

void printPlayerStatus();
// Player. cpp

void Player::printPlayerStatus(){
	cout << endl;;
}

이런식으로 적음

0개의 댓글