전체 글 131

#50. 함수 포인터

*함수포인터 선언 typedef int (*FUNC_TYPE)(int, int); using FUNC_TYPE = int(*)(int, int); FUNC_TYPE fn = Add; FUNC_TYPE fn = &Add; cout 옛날 방식 using FUNC_TYPE = int(int, int); => Morden C++ FUNC_TYPE* fn = Add; FUNC_TYPE* fn = &Add; cout _rarity > 10); } *단점은 '함수 시그니처' 를 맞춰야한다는 점. 유동적이진 못하다. *typedef 의 진실 => int 는 NUMBER 이다. typedef int NUMBER; => 변수가 복잡해지면 단순해지지 않음. => 왼쪽 오른쪽 이라고 생각하지말고 [선언 문법] 에서 typed..

프로그래밍/C++ 2022.07.20

#49. 전방 선언

해당 객체가 존재한다는 표시 용도 보통 해당 객체 내에 객체를 사용 시 포인터로 주소를 받게 되는데 이 때 사용 @해당 객체는 몇 바이트인가 ?? 헤더 추가가 필요 없다! why ?? Monster 가 어떤 데이터를 가지고 있는지 몰라도 Player 에서는 Monster* 를 저장하기 때문에 임시적으로 class Monster 를 적어두는 표시해두고 포인터 (주소받는곳,4/8바이트 고정크기 ) 를 선언해 Monster 객체의 주소를 받는다. 결국, 불필요한 헤더파일 추가를 피할 수 있다. class Monster; class Player { public: int _hp = 0; int _attack = 10; Monster* m1; }; 본 내용은 인프런의 루키스님 강의를 듣고 정리한 내용입니다. 강의 ..

프로그래밍/C++ 2022.07.20

#48. C++ 캐스팅

https://docs.microsoft.com/ko-kr/cpp/cpp/static-cast-operator?view=msvc-170 *static_cast => 문법적으로 가능하다면 형변환을 가능하게 해줌. => 타입 원칙에 비춰볼 때 상식적인 캐스팅만 허용. => 런타임 검사가 이루어지지 않음. 1. int -> float 2. Player* -> Knight* ( 다운캐스팅 ) 가능. => '안정성' 은 보장 못함 Player* p1 = new Player(); Knight* k1 = static_cast(p1); 결국, 컴파일 타임에 형변환에 대한 오류를 잡아줌. https://docs.microsoft.com/ko-kr/cpp/cpp/dynamic-cast-operator?view=msvc-1..

프로그래밍/C++ 2022.07.20

#47. 깊은 복사 & 얕은 복사

*얕은 복사 ( 컴파일러가 재정의되지 않아도 자동으로 생성 ) => 데이터를 단지 복사. => 멤버 데이터를 비트열 단위로 '똑같이' 복사 ( 메모리 영역 값을 그대로 복사 ) *깊은 복사 ( 객체 내 멤버변수로 포인터 & 참조 가 존재할 때 ) 복사생성자 / 복사 대입연산자 재정의 => 클래스 내의 포인터가 존재하고 그 포인터에 생성하는 클래스마다 각기 다른 주소를 담아야한다면 명시적 복사 생성자 / 복사 대입연산자를 정의해야 한다. *해당 클래스에 다른 클래스를 단지 선언만 해준다면 어떤 문제가 있나 ?? 1. 선언된 클래스가 크기가 크다면 해당 클래스도 비대해짐. 2. 해당 클래스가 소멸될 때 선언된 클래스도 같이 사라짐 => 생성/삭제 시점을 관리할 수 없음. => 생명주기 관리가 어려워짐. 3...

프로그래밍/C++ 2022.07.20

#46. 타입변환

@타입 변환 유형 ( 비트열 재구성 여부 ) 1. 값 타입 변환 => 의미를 유지하기 위해서, 원본 객체와 다른 비트열 재구성 int a = 0x12345678; //@2의 보수 float b = (float)a; //@부동소수점 cout 비트열을 재구성하지 않고, '관점' 만 바꾸는 것 => 거의 쓸일은 없지만, 포인터 타입 변환도 '참조 타입 변환' 과 동일한 룰 int a = 12345678; // @2의 보수 float b = (float&)a; // @부동소수점 cout short , int -> double .... 2. 불안전한 변환 => 의미가 항상 100 % 라고 보장 못함. => 타입이 다르거나, 큰 바구니 -> 작은 바구니 이동. @프로그래머 의도에 따라 분류 1. 암시적 변환 => ..

프로그래밍/C++ 2022.07.20

#45. 동적할당

*실행할 코드가 저장되는 영역 => 코드 영역 *전역 / 정적 변수 => 데이터 영역 => 프로그램이 종료될 때까지 '무조건' 사용되는 영역 *지역 변수 / 매개 변수 => 스택 영역 => 함수가 끝나면 같이 정리되는 불안정한 메모리 *동적할당 => 힙 영역 => 왜 사용해야할까 ?? => 스택 으론 엄청난 데이터를 생성할 수 없다. => 데이터영역으론 아쉽다. Player player[ 500 * 1000000 ]; 만약 접속자가 1000명이면 ?? , 나머지 데이터는 낭비. => 항상 최대 상한선으로 메모리를 잡아야한다는 것이 문제 => 필요할 때만 사용하고, 필요없으면 반납할 수 있는 우리가 생성 / 소멸 시점을 관리할 수 있는 영역 *유저 영역 메모장, LOL, 곰플레이어 .... @@@@@@@@..

프로그래밍/C++ 2022.07.20

#44. 연산자 오버로딩

*다시 정의할 수 있는 연산자 / 없는 연산자 https://docs.microsoft.com/ko-kr/cpp/cpp/operator-overloading?view=msvc-170 => operator*( ) 재정의 가능함. *연산자 vs 함수 => 연산자는 피연산자의 개수가 상관이 없다. b++; => ( 피연산자 1개 ) ++b; => ( 피연산자 1개 ) a + b => ( 피연산자 2개 ) *연산자 오버로딩 연산자 함수도 두 가지 방식으로 만들 수 있음. => 모든 연산자를 다 오버로딩 할 수 없음. *멤버 연산자 함수 version pos3 = pos1 + pos2 => pos1.operator+(pos2) a op b 형태에서, a => '기준 피연산자' 라고함. 한계 : a(왼쪽) 가 클래..

프로그래밍/C++ 2022.07.20

#43. 초기화 리스트

*초기화를 왜 해야할까 ?? => 버그 예방 중요 => 포인터 등 주소값이 연루되어 있을 경우 Knight k; cout 멤버변수 선언 시, 바로 초기화 int _hp = 100; *생성자 내 vs 초기화리스트 => 일반 변수는 차이 없음. => 멤버 타입이 클래스인 경우 차이. public: int _hp; Inventory _inventory; => 이 경우, _inventory 가 선처리 영역에서 같이 만들어지게 됨. 이 때, Inventory 생성자 호출 만약 다른 생성자 호출을 생성자 내에서 하게 된다면, 위 그림처럼, call Inventory (0B512D0h) call inventory::Inventory (0B51366h ) 즉, 생성자가 두 번 호출되게 됨. 따라서, 클래스 타입의 멤버..

프로그래밍/C++ 2022.07.20

#42. 다형성 virtual

*virtual 로 선언된 함수를 자식에서 재정의했을때 자식클래스 vptr은 부모인가?자식에있는 함수인가?? => 당연히 자식에 있는 함수 포인터로 저장됨. => 마지막으로 재정의된 함수포인터를 가지고 있음. *부모클래스 선언시 vptr 이 생기나?? => 반드시 생김. virtual 함수가 존재하면 객체 생성 시, 생성자 이전 '선처리 영역' 에서 vftable offset 저장. => 각 객체마다 독립적인 vfptr 을 가지고 있음. *다형성 ( Polymorphism ) *오버로딩 => 함수의 이름을 재사용 *오버라이딩 => 함수를 재정의 *정적 바인딩 ( Static Binding ) : 컴파일 시점에 결정 => 일반적인 함수 * 동적 바인딩 ( Dynamic Binding ) : 실행 시점에 결..

프로그래밍/C++ 2022.07.19

#41. 은닉성

*Data Hiding / Encapsulation => 몰라도 되는 것은 깔끔하게 숨기겠다. *캡슐화 => 연관된 데이터와 함수를 논리적으로 묶어놓는 것 *왜 숨겨야하는가 ?? 1. 정말 위험하고 건드리면 안되는 경우 2. 다른 경로로 접근하길 원하는 경우 *접근 지정자 public / protected / private *상속 접근 지정자 => 부모한테 물려받은 유산을 꼭 나의 자손에게 똑같이 물려줘야하지 않음. public : 거의 public 을 씀. (public -> public , protected -> protected ) protected : ( public -> protected, protected -> protected ) private : ( public -> private , pr..

프로그래밍/C++ 2022.07.19