nullptr포인터 레퍼런스 nullptr 클래스 생성자 소멸자 초기화 리스트``가상 소멸자 함수 오버로딩 템플릿 자손 클래스 업캐스팅
nulltprnew - delete 는 같이.private은 객체 기준이 아니라 클래스 기준이다._CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);public - protected - privateHuman():Height(0.0f), Age(0){} 식으로 생성자 만들자template <typename T>private 변수용 getter 함수 setter 함수 만들어 두기Warrior::Warrior(std::string inputName) : Player(inputName)Player* myPlayer = nullptr; 로 시작while + switch 로 직업 선택 구현 가능delete 하고 nullptr 처리Script* InPtrToScript 는 원본 자료형 크기와 관계없이 8바이트int& RefToA = A; -> 선언과 동시에 초기화 필수// Human.h
bool IsFriend(const char* InName);
bool IsFriend(int InID);
// Main.cpp
bool IsFriend = Human01->IsFriend(NULL);
//여기서 int InID가 호출
//why? NULL은 정수0을 반환
nullptr: C++에서 쓰는 정수로 변환되지 않는 포인터 상수// Main.cpp
class 클래스명
{
public:
멤버변수자료형 멤버변수명;
//이 객체, 물체의 "속성"
반환자료형 멤버함수명(매개변수자료형 매개변수명) {}
//이 객체, 물체가 해야 하는 "행동"
};
int main(void)
{
클래스명 객체이름;
return 0;
}
Human Kim;: 스택 메모리에 생성Human* Kim = new Human() : 동적 할당. 힙 메모리delete Kim; 필수!! =nullptr; 까지_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);public: 어디서나 접근 가능protected: 멤버 함수, 자식 클래스에서 접근 가능private: 멤버 함수에서만 접근 가능publicprivateclass 클래스명
{
public:
클래스명(){생성하면서할내용}; // 이게 생성자
~클래스명(){}; //이건 소멸자
}
int main()
{
Human Human01 = Human();
// 생성자를 명시적으로 호출해서 객체를 만들고, 그걸 다시 Human01에 대입.
Human* Human02 = new Human();
// 생성자의 명시적 호출.
Human Human03;
// 생성자의 암시적 호출.
Human* Human04;
// 포인터라 선언은 해드림. dangling pointer
return 0;
}
Human() : Height(0.0f), Weight(0.0f){} 식임float Height = 0.0f;) 생성 이후 초기화MC 만들고 main 함수에 MC MyClass; 하면 왜 생성됨? 생성자 클래스 내에 안만들어놨는데?class 안에 Human(){}; 생성자가 들어가 있는 꼴class Samsung: public Phone{};virtual ~phone(){}: 포인터로 자손 클래스 받아올 때도 제대로 소멸자 발동하려면 이렇게 쓰는 게 맞다.Phone* arrayPhones [3] = { new Samsung, new Apple, new Xiaomi };new Samsung()이 아닌.virtual void displayBrand() = 0;int/ 실수를 더한다 float 라는 개념을 하나로 합쳐서 관리할 수 있게 됨print(int a){} 함수와 print(float a){} 함수 동시 구현add(int a, int b){} 와add(int a, int b, int c){}print(10) 한다 쳤을 때 함수 매개변수들이 float long 이다? int는 둘 다 변환 가능 void display(int a, int b=5): b 는 디폴트 매개변수. b 지정해서 안 넘겨주면 인자 하나짜리 함수랑 똑같이 작동함. 그래서 display(int a)랑 중복됨. void print(int* arr), void print(int arr[])int getValue(), double getValue() 이런 경우에도 안됨
print(10) -> void print(int a) over void print(double a)char, short -> intfloat -> doublebool -> intint -> doubledouble -> intdouble -> floatprint(double a) 는 뭘 선택할까?void print int >>> void print stringtemplate <typename T> 맨 위에 추가: 어떤 타입이 올 지 모르겠으나, 그 자료형을 T 라고 부르겠다.T 사용하면 됨.template <typename T>
T add(T a, T b) {
return a + b;
}
T getMax() 함수로 (a > b)? a : b; 만들어서 string 비교도 가능. 사전순으로 더 뒤쪽의 값을 반환template <typename T>
void printArray(T arr[], int size) {
for (int i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
size는 무조건 int니까 템플릿으로 넣을 이유가 없다.printArray(intArr, 3); 식으로 프린트 가능template <typename T>
void swapValues(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
Warrior, Magician, Thief, Archer 구현하고Player* myPlayer = nullptr; 로 업캐스팅.while-switch로 무한루프 구현while (selectPending)
{
switch (selectMenu)
{
case 1:
myPlayer = new Warrior(nickname);
selectPending = false;
break;
......
default:
std::cout << "Invalid input. Pick a number from 1 to 4." << std::endl;
std::cin >> selectMenu;
break;
}
}
if (myPlayer != nullptr)
{
delete myPlayer;
myPlayer = nullptr;
}
Player 스탯 같은 초기화는 엔간하면 생성자 내부 {} 안이 아니라 이니셜라이저로Player::Player(std::string inputName): nickname(inputName), level(1), HP(100),MP(100),power(10),defense(10),accuracy(10),speed(10)getter 함수와 setter 함수는 기능적으로 있으면 나쁠 게 없는 함수들이 만들어 놓긴 했다반환자료형 get변수명(){
return 변수명;
}
void set변수명(매개변수자료형 a){
변수명=a;
return;
}
.h 와 소스코드 .cpp 둘 다 해야 하는 걸 잊지 말자.void printPlayerStatus();void printPlayerStatus(){}std::string inputname을 받더라도Warrior::Warrior(std::string inputName) : Player(inputName) 식으로 넘겨줘야 한다jobName 플레이어스테이터스에 표시해 주는 함수도 멤버 함수로 만들어서 생성자에 포함시켜 player.jobName 초기화 시켜줌.