포인터 (이어서)
가상함수 포인터 vfptr
{
int Arr[10];
int* Ptr = Arr;
int* PtrArr[10];
int** PtrPtrArr = PtrArr;
}
{
int Value0;
int Value1;
int* ArrPtr[2];
ArrPtr[0] = &Value0;
ArrPtr[1] = &Value1;
int** Ptr2D = ArrPtr;
}
{
int *Value0;
int *Value1;
int** ArrPtr[2];
ArrPtr[0] = &Value0;
ArrPtr[1] = &Value1;
int*** Ptr2D = ArrPtr;
}
{
void(*Value0)();
void(*Value1)();
void(**ArrPtr[2])();
ArrPtr[0] = &Value0;
ArrPtr[1] = &Value1;
void(***Ptr2D)() = ArrPtr;
}
class FightUnit
{
public:
FightUnit()
{
this;
}
virtual void Damage()
{
}
virtual void StatusRender()
{
}
};
class Player : public FightUnit
{
public:
Player()
{
this;
}
void Damage() override
{
}
};
int main()
{
int Size = sizeof(FightUnit);
Player NewPlayer = Player();
}
- this 0x000000f8048ffae8 {...} FightUnit *
- __vfptr 0x00007ff7fb20ac30 {Test4.exe!void(* FightUnit::`vftable'[3])()} {0x00007ff7fb201145 {Test4.exe!FightUnit::Damage(void)}, ...} void * *
[0] 0x00007ff7fb201145 {Test4.exe!FightUnit::Damage(void)} void *
[1] 0x00007ff7fb20134d {Test4.exe!FightUnit::StatusRender(void)} void *
- this 0x000000f8048ffae8 {...} Player *
- FightUnit {...} FightUnit
- __vfptr 0x00007ff7fb20ac50 {Test4.exe!void(* Player::`vftable'[3])()} {0x00007ff7fb2012a3 {Test4.exe!Player::Damage(void)}, ...} void * *
[0] 0x00007ff7fb2012a3 {Test4.exe!Player::Damage(void)} void *
[1] 0x00007ff7fb20134d {Test4.exe!FightUnit::StatusRender(void)} void *
#include <iostream>
void(*vfptrArr[4])() = {};
void(**vfptr)() = vfptrArr;
void FightUnitStatusRender()
{
printf_s("스테이터스 렌더 함수");
}
void FightUnitDamage()
{
printf_s("파이트 유니트 데미지 함수");
}
void FightUnitFightEnd()
{
printf_s("파이트 유니트 데미지 함수");
}
void FightUnit()
{
vfptr[0] = FightUnitStatusRender;
vfptr[1] = FightUnitDamage;
vfptr[2] = FightUnitFightEnd;
}
void PlayerDamage()
{
printf_s("플레이어 데미지 함수");
}
void Player()
{
vfptr[1] = PlayerDamage;
}
int main()
{
FightUnit();
Player();
vfptr[0]();
vfptr[1]();
int Value0 = sizeof(vfptr);
int Value1 = sizeof(vfptrArr);
}
사용자 정의 자료형
enum
enum Job
{
Fighter,
Mage
};
enum class DamageType
{
PDamage,
MDamage
};
enum class Test
{
Test0 = 'a',
Test1
};
class Player
{
public:
Job JobType;
DamageType Type;
};
int main()
{
{
Job Fighter = Job::Fighter;
int FighterInt = Job::Fighter;
int MageInt = Job::Mage;
}
{
DamageType Type = DamageType::MDamage;
int Value0 = static_cast<int>(Type);
int Value1 = (int)Type;
}
}
typedef와 using
enum class Job
{
Fighter,
Mage
};
typedef int int32;
typedef Job JobType;
using myint = int;
struct _PlayerData
{
};
typedef struct _PlayerData PlayerData;
int main()
{
struct _PlayerData NewPlayerData;
PlayerData NewPlayerData;
myint A = 20;
}
cout
namespace
#include <iostream>
namespace UI
{
class Item
{
public:
Item()
{
printf_s("인벤토리 아이템");
}
};
}
namespace Play
{
namespace Monster
{
class Item
{
public:
Item()
{
printf_s("몬스터 드랍 아이템");
}
};
}
}
class Item
{
public:
Item()
{
printf_s("전역 아이템");
}
};
int main()
{
Item NewItem;
UI::Item NewUIItem;
Play::Monster::Item NewPlayItem;
std::cout << "Hello World!\n";
}
구현
#include <iostream>
namespace std
{
class MyStream
{
public:
void operator <<(const char* _Text)
{
printf_s(_Text);
}
};
extern MyStream mycout;
}
std::MyStream mycout;
int main()
{
std::mycout << "Hello World!\n";
std::mycout.operator<<("Hello World!\n");
}
동적 할당
new
class Monster
{
};
class Zone
{
};
int GValue = 10;
int main()
{
{
int LValue = 10;
int* Ptr = new int(10);
delete Ptr;
}
{
Zone* CurZone = nullptr;
if ()
{
CurZone = new Zone();
}
}
}
메모리 누수 memory leak
#include <iostream>
class Monster
{
int Hp;
int Att;
int Def;
};
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
{
Monster* NewMonster = new Monster();
delete NewMonster;
}
{
int ArrCount = 10;
Monster NewArr[ArrCount];
int MonsterCount = 10;
int PlayLevel = 1;
if (PlayLevel > 20)
{
MonsterCount = 30;
}
Monster* NewMonster = new Monster[MonsterCount];
delete[] NewMonster;
}
}
(leak 체크 결과 예시)
Detected memory leaks!
Dumping objects ->
{75} normal block at 0x0000026C89A3F320, 12 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00
Object dump complete.
Console Game (enum ver.)
- 상하좌우, 발포 키에 enum class 적용
#pragma once
enum class KeyType
{
LeftKeyS = 'a',
LeftKeyB = 'A',
RightKeyS = 'd',
RightKeyB = 'D',
UpKeyS = 'w',
UpKeyB = 'W',
DownKeyS = 's',
DownKeyB = 'S',
FireKeyS = 'q',
FireKeyB = 'Q',
};
#include "Player.h"
#include <conio.h>
#include "ConsoleScreen.h"
#include "GameEnum.h"
Player::Player()
{
}
Player::Player(const int2& _StartPos, char _RenderChar)
: ConsoleObject(_StartPos, _RenderChar)
{
}
void Player::Update()
{
KeyType Value = static_cast<KeyType>(_getch());
switch (Value)
{
case KeyType::LeftKeyS:
case KeyType::LeftKeyB:
{
if ((Pos + Left).X != 0)
{
Pos += Left;
}
break;
}
case KeyType::RightKeyS:
case KeyType::RightKeyB:
{
if ((Pos + Right).X != (ScreenX - 2))
{
Pos += Right;
}
break;
}
case KeyType::UpKeyS:
case KeyType::UpKeyB:
{
if ((Pos + Up).Y != 0)
{
Pos += Up;
}
break;
}
case KeyType::DownKeyS:
case KeyType::DownKeyB:
{
if ((Pos + Down).Y != (ScreenY - 1))
{
Pos += Down;
}
break;
}
case KeyType::FireKeyB:
case KeyType::FireKeyS:
{
if (nullptr != IsFire)
{
*IsFire = true;
}
}
default:
break;
}
}
void Player::SetBulletFire(bool* _IsFire)
{
if (nullptr == _IsFire)
{
return;
}
IsFire = _IsFire;
}
과제
#include <iostream>
#include <string.h>
int StringCount(const char* _Ptr)
{
int Count = 0;
while (_Ptr[Count])
{
++Count;
}
return Count;
}
enum class StringReturn
{
Equal,
NotEqual
};
StringReturn StringEqual(const char* const _Left, const char* const _Right)
{
int LCnt = StringCount(_Left);
int RCnt = StringCount(_Right);
if (LCnt != RCnt)
{
return StringReturn::NotEqual;
}
for (int i = 0; i < LCnt; i++)
{
if (_Left[i] != _Right[i])
{
return StringReturn::NotEqual;
}
}
return StringReturn::Equal;
}
void StringAdd(char* _Dest, const char* const _Left, const char* const _Right)
{
int LCnt = StringCount(_Left);
int RCnt = StringCount(_Right);
for (int i = 0; i < LCnt; i++)
{
_Dest[i] = _Left[i];
}
for (int i = 0; i < RCnt; i++)
{
_Dest[LCnt + i] = _Right[i];
}
_Dest[LCnt + RCnt] = 0;
return;
}
int StringContains(const char* const _Dest, const char* const _Find)
{
int DCnt = StringCount(_Dest);
int FCnt = StringCount(_Find);
if (DCnt < FCnt)
{
return 0;
}
int Cnt = 0;
for (int i = 0; i < DCnt; i++)
{
if (i > DCnt - FCnt)
{
break;
}
for (int j = 0; j < FCnt; j++)
{
if (_Dest[i + j] != _Find[j])
{
break;
}
if (j == FCnt - 1)
{
Cnt += 1;
}
}
}
return Cnt;
}
int main()
{
{
int Count0 = StringCount("AAA");
int Count1 = static_cast<int>(strlen("AAA"));
}
{
StringReturn IsEqual0 = StringEqual("AAAA", "AAAA");
StringReturn IsEqual1 = StringEqual("AAAAA", "AAAA");
int Result0 = strcmp("AAAA", "AAAA");
int Result1 = strcmp("AAAAA", "AAAA");
}
{
char Arr0[100] = {};
StringAdd(Arr0, "abcd", "efgh");
char Arr1[100] = {};
StringAdd(Arr1, "gfadsgf", "fasdfsda");
char ArrTest[100];
sprintf_s(ArrTest, "%s%s", "AAAAA", "BBBBB");
}
{
int Cnt0 = StringContains("ababcccccabab", "ab");
int Cnt1 = StringContains("ababcccccabcdab", "abcd");
int Cnt2 = StringContains("eafknvkiojfknvfknvkfdahfknvk", "fknvk");
}
}