반응형
잠깐 알아가보기 전에 잡설을 해보겠다....
보고싶은 분은 접은글을 봐주시길....★
더보기
불과 몇달 전에 한 프로젝트 중에 이런 난잡한 코드를 썼다.
void InGameHumanBox::Update()
{
if (human)
{
if (Utillity.CheckBaseClass<TutorialHuman>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV();
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
if (Utillity.CheckBaseClass<Woman01>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV();
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
if (Utillity.CheckBaseClass<Woman01>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV();
m_gauge->index = ((int)human->GetHorrorScore()/10) + 25;
}
if (Utillity.CheckBaseClass<Woman02>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV() + 8;
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
if (Utillity.CheckBaseClass<Woman03>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV() + 16;
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
if (Utillity.CheckBaseClass<Man01>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV() + 4;
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
if (Utillity.CheckBaseClass<Man02>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV() + 12;
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
if (Utillity.CheckBaseClass<Man03>(human))
{
m_name->SetText(human->gameObject->GetName());
m_profile->index = (int)human->GetHorrorLV() + 20;
m_gauge->index = ((int)human->GetHorrorScore() / 10) + 25;
}
}
}
CheckBaseClass()가 무슨 메소드냐면....
그렇다 그냥 인자로 받은 human친구가 템플릿 인자로 받은 클래스를 상속받았으면 true를 반환해주는 클래스다.
하지만 이런 삽질을 간단하게 만들어주는 편한 메소드를 찾아냈다...!
is_base_of 클래스 | Microsoft Learn
오늘은 이 클래스에 대해 소개해보겠슴덩
template <class Base, class Derived>
struct is_base_of;
말그대로 Derived클래스가 Base클래스를 상속받은건지 알려주는 클래스인데요?
이걸로 편하게 상속받은 클래스를 확인해보시죠 ㅇㅅㅇ
근데 이렇게만 쓰면 섭섭하죠?
특정 객체와 클래스를 인자로 넘겨주면 해당 클래스를 상속받은건지 확인해주는 메소드를 작성해보겠습니다.
#include "pch.h"
#include <type_traits>
struct Human{};
struct Human01 : public Human{};
struct Human02 : public Human{};
struct Human03 : public Human{};
// P클래스를 상속받은 클래스면 true를 반환한다.
template <typename P, typename C>
bool CheckBaseClass(C _dest) {
return std::is_base_of<P, C>::value;
}
int main()
{
Human _human;
Human01 _human01;
Human02 _human02;
Human03 _human03;
std::cout << std::boolalpha;
std::cout << "human01 is base of Human : " << CheckBaseClass<Human>(_human01) << '\n';
std::cout << "human02 is base of Human : " << CheckBaseClass<Human>(_human02) << '\n';
std::cout << "human03 is base of Human : " << CheckBaseClass<Human>(_human03) << '\n';
std::cout << "=================================" << '\n';
std::cout << "human01 is base of Human01 : " << CheckBaseClass<Human01>(_human01) << '\n';
std::cout << "human02 is base of Human01 : " << CheckBaseClass<Human01>(_human02) << '\n';
std::cout << "human03 is base of Human01 : " << CheckBaseClass<Human01>(_human03) << '\n';
return (0);
}
출력결과
human01 is base of Human : true
human02 is base of Human : true
human03 is base of Human : true
=================================
human01 is base of Human01 : true
human02 is base of Human01 : false
human03 is base of Human01 : false
그럼 여기서 궁금한 점 하나...
dynamic_cast와 is_base_of 와 성능차이는 얼마나 날까요? 성능차이가 나지 않으면 굳이 쓸 이유가 없는 코드죠?
그래서 코드로 확인을 해봤습니다...
더보기
#include "pch.h"
#include <iostream>
#include <type_traits>
#include <chrono>
struct Human {};
struct Human01 : public Human {};
struct Human02 : public Human {};
struct Human03 : public Human {};
template <typename P, typename C>
bool CheckBaseClass(C* _dest) {
return std::is_base_of<P, C>::value;
}
template <typename P, typename C>
bool CheckDynamicCast(C* _dest) {
P* temp = dynamic_cast<P*>(_dest);
return temp != nullptr;
}
int main()
{
Human01* _human01 = new Human01();
Human02* _human02 = new Human02();
Human03* _human03 = new Human03();
const int iterations = 100000000; // 반복 횟수 설정
// std::is_base_of 시간 측정
auto startIsBaseOf = std::chrono::high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
CheckBaseClass<Human>(_human01);
}
auto endIsBaseOf = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsedIsBaseOf = endIsBaseOf - startIsBaseOf;
std::cout << "std::is_base_of time: " << elapsedIsBaseOf.count() << " seconds\n";
// dynamic_cast 시간 측정
auto startDynamicCast = std::chrono::high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
CheckDynamicCast<Human>(_human01);
}
auto endDynamicCast = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsedDynamicCast = endDynamicCast - startDynamicCast;
std::cout << "dynamic_cast time: " << elapsedDynamicCast.count() << " seconds\n";
delete _human01;
delete _human02;
delete _human03;
return 0;
}
결과 (4번 시행)
2트때 차이가 너무 안나서 엥? 했다가 여러번 해보니까 나름 격차가 좀 있네요 ㅇㅅㅇ
그래서 어따씀?
에 대한 의문이면 게임엔진으로 따져보면 AddComponent같은 곳에 쓰지 않을까요?
오늘도 개꿀팁(?)을 알려드렸는데요?
이상으로 글을 마쳐보겠습니다. 감사합니다?
반응형
'프로그래밍 > C++' 카테고리의 다른 글
[C++] auto의 타입 추론에 대하여 알아보자.araboza (C++11) (0) | 2024.09.13 |
---|---|
[C++] 복사 생성자(+복사 대입 연산자)를 알아보자.araboza (4) | 2024.09.12 |
[C++] 생성자 상속(C++11) (1) | 2024.09.06 |
[C++] String 클래스 구현해보기 (0) | 2024.07.26 |
[C++] DFS 구현해보기 (0) | 2024.07.10 |