C++ 라이브 세션
생성자와 소멸자
기본 생성자와 오버로딩
- 생성자를 클래스 내에서 만들면 기본생성자 자동생성 X
MyClass Object01; 식으로 선언해서 기본생성자로 생성 불가능
MyClass Object01 = MyClass(); 필요
- 생성자도 함수니 매개변수 달리 해서 오버로딩 가능
소멸자
- 객체가 소멸될 때 자동호출되는 함수
- 포인터로 동적할당해서 생성한 클래스는
delete 안하면 소멸자 소환 안됨에 주의
- 명시적 호출 (거의)불가 - 오버로딩도 불가능
- 포인터로 생성한 건 가능하긴 하다
Ptr01->~MyClass();
- 근데 쓸 일은 없긴함. 메모리 해제도 해줘야하긴 하니까
RAII
- 하나의 "패턴"
- 객체에게 필요한 자원을 생성자에서 획득,
소멸자에서 획득한 자원을 해제하도록 설계하는 게 필수
char* Name = new char[8] 생성자에서 만들었으면
소멸자에서 delete Name[] 하고 가라
-C언어에서 malloc() free()와 new delete의 가장 큰 차이: 생성자/소멸자 자동호출된다는 점
Const 멤버 함수
void PrintInfo() const; 처럼 선언
- 클래스 내부의 함수면서 클래스 멤버 변수를 수정하지 못하는 함수. 출력용, getter 함수에 많이 쓰임
- 꼭 '필요' 는 없지만, 사고 방지용으로
캡슐화. Getter. Setter
- 객체지향프로그래밍 원칙 중 하나:
캡슐화
- 클래스의 멤버 변수를 외부에서 직접 접근을 막음
- 꼭 필요할 때 쓰는 게
get, set 함수들.
- 각 클래스 내에서 input 조건에 예외조항을 막는 if문 넣을 수도 있고, 넣는 방식을 결정할 수 있고, 여러모로 도움
클래스 전방 선언과 friend 키워드
class PlayerCharacter
{
public:
Inventory MyInventory;
};
class Inventory
{
};
int main(void)
{
return 0;
}
- 컴파일러는 위에서부터 아래로 읽는다
- Inventory가 뭔지 모르는데
Inventory MyInventory 를 부르면? 에러
전방선언의 필요성 - 함수도, 클래스도 동일
class PlayerCharacter;
class Inventory;
class PlayerCharacter
{
public:
Inventory MyInventory;
}
이런 식으로.
- 전방 선언 특: 안해서 문제생기면 "전방 선언" 관련 에러는 안나오고 이상하게 에러가 많이 뜬다. 항상 체크하기
- 헤더 vs 전방선언?
- 전방선언은 "클래스의 크기" 를 알려주지 않는다
- 클래서 내부의 자료들이 필요할 때 에러가 날 가능성 큼
- 헤더는 많아질수록 하나 수정할 때마다 재컴파일 개 길다
- 객체 포인터 자료형은 전방 선언
- 객체 '값' 자료형을 써야 할 때는
#include
friend 키워드
- 다른 클래스/함수에서 내 클래스의
private, protected 멤버에 접근 가능
class Human
{
friend class Bestfriend;
......
};
class Human;
class Bestfriend
{
public:
void PrintYourInfo(const Human& inPerson);
};
- 함수도 전역 함수를
friend float GetBMI() 이러면 멤버에 접근 가능.
MyClass.cpp 에 꼭 해당 클래스의 멤버에 대해서만 적을 필요가 없다! 그냥 관례에 가까움
- MyClass 관련해서 사용하는 전역 함수에 대한 정의를 여기서 적어도 된다.
복사 생성자와 오버로딩
오버로딩은 왜 필요한가?
- 자료형 다르다고 "동작" - 즉 함수가 달라질 이유는 없다.
int + int 나 float+float 이름을 매번 동의어로 하는 건 피곤하고 중복적
오버로딩
- 같은 이름이지만 매개변수 목록은 다르게 함수를 재정의
함수를 비슷하게 다시 작성하는 경우
- 함수 중복 정의(컴파일 에러)
- 함수 오버라이딩
- "자손 클래스" 에서 같은 걸로 멤버 함수 재정의
- 함수 오버로딩
- 같은 이름, 다른 매개변수 목록
- 반환 자료형 은 오버로딩 판단 기준이 아니다
반환 자료형만 다른 함수는?
- 반환 자료형 가리고 보고 매개변수/이름이 같으면 -> 중복 정의로 컴파일러는 판단
C++ 과제
도전 과제 완성
- 포인터로 플레이어는 몬스터를, 몬스터는 플레이어를 받는 과정에서 서로 헤더 파일을
#include 하면 #pragma once 때문에 제대로 안받는다
- 해결책은 각 헤더 파일들에선 (어차피 포인터만 받으니)
class Monster; 식으로 전방 선언만 해두기
- 실제 멤버들 받아와야 하는 소스코드 파일
Player.cpp Monster.cpp 에서 헤더 include 하는 식으로 할 것. 정확히는 attack() 이 순수가상함수니 각 자손 클래스들 소스 코드에 include 필요!!
Monster 포인터 추가했으니 delete 도 잊지 말 것. 그 외엔 여태까지 배운 조건문/반복문 잘 조합해서 전투과정 만들면 된다.