TIL: C++ TextRPG 개발 23일차

박춘팔·2026년 4월 30일

언리얼 TIL

목록 보기
22/26

누적 학습 시간 : 212시간 34분

📅 2026-04-30

가상함수와 추상클래스

참고: https://baggu4402.tistory.com/15

TRPG 개발 중 캐릭터의 직업클래스와 부모 클래스를 만들면서 사용할 일이 있어서 알아봤다.

C++에서는 java처럼 abstact같은 키워드가 없다.

순수가상함수가 포함되어 있는 클래스는 추상클래스로 취급되고 순수가상함수는 상속받는 자식클래스에서 반드시 구현해야한다.

순수 가상 함수는 부모의 강제 규칙, 오버라이딩은 자식의 실제 구현.

class Job
{
public:
	virtual Stat SetBaseState() const = 0;
    virtual std::string GetJobName() const = 0;
}

class Warrior : public Job
{
	Stat SetBaseState() const override
    {
		...구현...
    }
    std::string GetJobName() const override
	{
		...구현...
	}
}

TS interface 생각하면 편함!

사실 class는 뭐 HttpClient 구현체 만들때나 쓰고 일부 백엔드 작업하면서나 써봤지 알고는 있지만 쓸일이 그닥 많지는 않았다.

어렵게 생각하지말고 내 입장에서는
추상클래스 = interface 라고 생각하면 기초수준에서의 이해는 되는 것 같다.

다만 다른점은 C++ 추상클래스는 클래스가 구현을 포함할 수 있고 TS interface는 구현을 위한 명세만을 다룬다는 점이다.
또한 TS interface는 ? 를 사용해 해당 함수가 상속받는 클래스 내부에 존재할수도 존재하지 않을 수도 있는 상태를 만들 수 있는데

C++에는 그런 방법이 없고 SOLID 원칙에서 안티패턴으로 간주하고 리팩토링을 하는 것을 권장하고있다.

에러케이스

#pragma once
#include <functional>
#include <map>
#include <string>

#include "Actor/Stat.h"

enum class JobState { Warrior, Mage };

class Job
{
    std::map<char, std::function<void()>> jobFuncMap;

public:
    virtual std::string Test();
    virtual Stat SetBaseStat() const = 0;
    virtual std::string GetJobName() const = 0;
};

순수가상함수 아니면 되는거 아니었나요?

순수가상함수는 구현할 필요가 없습니다. 왜냐?
자식클래스에서 반드시 구현해야 하기 때문에 추상클래스에서 구현할 필요가 없습니다.
하지만 일반 가상함수는 컴파일러가 어딘가에 구현이 있다고 생각하고 링크를 하다가 구현이 없으면 LNK에러가 발생하게 됩니다.

#pragma once
#include <functional>
#include <map>
#include <string>

#include "Actor/Stat.h"

enum class JobState { Warrior, Mage };

class Job
{
    std::map<char, std::function<void()>> jobFuncMap;

public:
    virtual std::string Test() { return "" } ;
    virtual Stat SetBaseStat() const = 0;
    virtual std::string GetJobName() const = 0;
};

그래서 위와같이 구현을 추가해주면 에러가 사라집니다.

랜덤

던전 이벤트 구현을 위해 C++에서는 랜덤을 어떻게 돌리나 검색을 해봤다.
그랬더니 나는 단순하게 Rand() 함수라던가.. 를 생각했는데
무슨 메르센 트위스터 알고리즘을 이용한 난수 생성기를 이용하는게 좋다더라.....
당최 무슨 소린지 모르겠지만 일단 써보고 랜덤을 사용해야할 경우에 계속 사용하다보면 익숙해지지 않을까 싶다.............

사용법

// 하드웨어 기반 난수 생성 시드
static std::random_device rd;

// tm19937 = 난수엔진
// 메르센 트위스터 알고리즘을 사용함
// gen(seed)를 통해 생성 > gen(rd())
static std::mt19937 gen(rd());

// 균등 분포 정수 생성기(?????)
// dist() 를 통해 범위 지정
static std::uniform_real_distribution<> dist(0, 2);

dungeonEventState = static_cast<DungeonEvent>(dist(gen))

0 > Nothing
1 > EncounterEnemy
2 > FindTreasure

static 키워드

static은 lifetime과 scope를 고정한다.

함수 내부 static

void A()
{
	static int a = 10; // 함수 끝나도 살아있음
}

최초 1회만 초기화 가능하며 함수 호출이 끝나면 값이 살아있다.

class 내부 static

class A 
{
	static int count; // 해당 class로 생성된 객체와 모두 공유됨
}

A a;
A b;

a.count // 10
b.count // 10

//하지만 static 멤버변수 호출은 아래가 정석 다 공유되니까!
A::count  // 10
profile
이것 저것 다해보는 삶

0개의 댓글