0. 필요성

헤더에서 정의된 클래스를 메인 함수에 만들면 스택 메모리에 저장이 된다.

단, 동적 할당으로 만들면 힙 메모리에 저장이 된다.

// --Player.h--
#pragma once

class Player
{
public:


public:
	int _hp;
	int _atk;
};
// --Main.cpp--
#include <iostream>
#include <stdlib.h>
#include "Player.h"
using namespace std;


int main()
{
	Player p1;
	Player* p2 = new Player();

	return 0;
}

여기서 player는 8바이트를 가지고 있다는 것을 알 수 있다(int 형 멤버 변수 2개를 들고 있음).

그렇다면 아래와 같이 다른 클래스의 객체를 들고 있는 player(Monster에 종속적임)는 몇 바이트를 들고 있을까?

#pragma once
#include "Monster.h"

class Player
{
public:
	Monster _target;

public:
	int _hp;
	int _atk;
};

_target이 포인터 형(4바이트 또는 8바이트)이 아닌 객체 그 자체일 때는 직접 까보지 않는 이상 알 수 없다.

 

따라서 포인터 형으로 만들면 player가 몇 바이트인지 확실하게 알 수 있다.

#pragma once
// #include "Monster.h"

class Monster;

class Player
{
public:
	Monster* _target;

public:
	int _hp;
	int _atk;
};

여기서 player는 int형 2개(8바이트), 포인터형 1개(8바이트)이므로 총 16바이트이다.

여기서 Player 클래스를 정의하기 전에 Monster를 먼저 선언하여 발생할 수 있는 오류를 미리 제거한다.

또는 다른 방법의 전방 선언도 있다.

#pragma once
// #include "Monster.h"

class Player
{
public:
	class Monster* _target;

public:
	int _hp;
	int _atk;
};

 

1. 전방 선언을 할까, 헤더 파일을 포함할까?

그러나 Player 클래스 내에 몬스터를 처치하는 함수를 만들때 문제가 발생한다.

// --Player.cpp--
#include "Player.h"

void Player::KillMonster()
{
	_target->_hp = 0;
}

몬스터 객체인 _target의 멤버 변수(_hp)에 접근할 수 없다. 따라서 몬스터의 헤더 파일을 포함해야한다.

#include "Player.h"
#include "Monster.h"

void Player::KillMonster()
{
	_target->_hp = 0;
}

즉, 객체 내의 멤버 변수에 접근하고자 하면 반드시 포함 방법을 사용하여야 한다.

또는 객체 내에 있는 함수에 접근할 때도 포함 방법을 사용하여야 한다.

'기초 C++ 스터디 > 객체지향' 카테고리의 다른 글

8-2. 함수 포인터(2)  (0) 2023.06.08
8-1. 함수 포인터(1)  (0) 2023.06.08
6-5. 캐스팅  (0) 2023.06.02
6-4. 얕은 복사, 깊은 복사  (0) 2023.06.01
6-3. 형(Type) 변환 : 포인터 (2)  (0) 2023.06.01