http://soen.kr/
digital_video_introduction/README-ko.md at master · leandromoreira/digital_video_introduction · GitHub
MediaCodec | Android Developers
MediaPlayer | Android Developers
43강] 개체 힙생성, 스택생성
- JAVA 는 Stack 에 개체를 생성 할 수 없다.
- C++ 은 Obj* o = new Obj(); //힙에 개체생성 // 연속적인 메모리를 직접 찾아야함
delete o; // 실행할 때 직접 삭제해야함
Obj o ; // 스택에 개체생성
// 스택이 삭제되지 않고 단지 스택 포인터만 함수가 끝나면 내려간다.
// 컴파일때 이미 개체의 크기를 알게된다.
// 스택포인터 움직임을 위한 크기 측정이 런타임에 필요없으니 더 빠름
43강] 다음은 동일한가요?
java vector[] list = new vector[10]; |
C++ vector* list = new vector[10]; |
자바는 개체 레퍼런스다. 자바에서 오브젝트 쓸 때 언제나 레퍼런스(포인터) 이다. vector 포인터 10개 들어가는 공간을 힙에 만들어 줘라. ( 10개의 4바이트짜리 nullptr ) stack 에는 list 라는 4바이트짜리 하나의 포인터가 있다. |
C++은 이런 혼돈이 없다. 그냥 진짜 벡터를 10개 만들어준다. 그리고 그 배열의 포인터가 stack 에 생성된다. vector**list = new vector*[10]; 이것이 왼쪽과 같다. |
44강] 소멸자
vector* list = new vector[10]; 의 소멸자를 작성해보자.
>delete[] list;// 첫번쨰 포인터만 소멸되게 된다. ( 배열인지 알려줘야지 배열의 모든 object들을 소멸해 준다. )
45강] 다음의 멤버변수 기본값들은?
JAVA | C++ |
class A{ private int a; private char b; } A a = new A(); |
class A{ private: int mA; char mB; } A a; A* a = new A(); |
둘다 0으로 초기화됨 힙에 들어가는 순간 (메모리 할당하고) 메모리를 채워 준다. C로 구현 할 수 있다. void* ptr = malloc( sizeof(A)); memset(0,sizeof(A)) return (A*)ptr; |
힙에 메모리를 잡는다. -> 전에 쓰던 어떤 가비지 값이 들어있다. -> 끝 ( 성능이 중요하니까 0대입 하고 싶으면 개발자 너가 직접 해라.) 즉, 가비지값이 들어가 있다. |
46강] JAVA 는 기본생성자 필요 x C++는 필요 왜?
C++는 0으로 초기화 해주지 않기 때문.
46강] C++의 초기화 리스트 와 대입의 차이, 그리고 초기화 리스트의 필요성.
C++ 대입 | C++ 초기화 리스트 |
class A { const int mA; obj& mO; A( obj& another ){ mA = 0; mO = another; } } |
class A { const int mA; obj& mO; A( obj& another ): : mA (0) , mO (another); { } A() : mA (0) , mO(0); //기본 생성자 0으로 초기화 버릇 들이자. { } } |
에러가 난다. 참조는 처음부터 초기화가 되어야 한다. mA는 변환이 불가능한 const 형태이다. |
성공한다. 초기화 리스트는 객체가 생성되는 순간 같이 초기화 되므로 둘다 가능하다. |
51강] 생성자의 오버로딩
여러개의 매개변수 갯수, 기본생성자 등 각기 다른 생성자를 여러개 만들수 있다.
51강] 소멸자
delete 을 사용할때 호출 된다.
기본 소멸자가 있지만, 다음의 경우에는 우리가 직접 생성해주어야 한다.
클래스 내부에서 동적 메모리할당 class A{ char* a; int len; A() : len(10) { a = new char[len+1]; } } |
delete A 했을때 a의 포인터는 삭제되지만, a가 가리키고 있던 메모리들은 삭제되지 않는다. |
class A{ char* a; int len; A() : len(10) { a = new char[len+1]; } ~A(){ delete[] a; } } |
이렇게 a를 삭제해줘야 한다. |
51강] 가상소멸자
virtual 함수에 대한 소멸자. virtual 은 자녀가 상속 받는데, 각 자녀마다 알맞은 소멸자를 사용해야 한다.
부모 * obj = new 자녀(); 일때 delete obj 하면 기본 소멸자는 부모의 소멸자를 호출한다.
그래서 소멸자에도 virtual 을 해주어야지 자기 껍데기에 맞는 소멸자를 호출한다.
52강] Const 멤버 함수
const 가 붙는것은 수정 불가능이라는 뜻이었다.
const int a;
그렇다면 다음의 함수는 어떨까?
int add(const Point& p) const{
mX = mX + p.x;
mY = mY + p.y;
} // 정답은 매개변수의 const 는 문제없음 ,마지막의 const 가 문제가 있다.
// 어떤값도 변경 시키면 안된다.
54강] 클래스와 struct 차이
기본값이 private , public 인 것 외에는 차이점이 없다. ( C 에서는 당연히 있었다. OOP 가 없었고, 함수를 만들어 struct 를 그 인자로 넘기는 등을 배웠었다. )
c++에서는 차이가 없는데, 하지만 사용 표준을 만들어서 사용하자.
rule1. struct는 완전 Plain Old Data 로만 사용해서, memcpy 가 가능하도록, 바로 파일에 작성할 수 있도록 하자. ( 메소드 x, 포인터 x 소멸자생성자 x )
rule2. struct는 생성사,소멸자, 포인터까지만 사용하자. public private 및 함수 는 없도록하자. ( memcpy 까지는 불가능 하지만, 클래스와 차이를 둘 수 있다.)
55] 복사생성자
클래스간 복사를 하려면 값들을 일일히 복사해주어야 했다. 그리고 포인터가 있는경우 똑같이 복사해줄 것인지, 기존 포인터를 공유할 것인지도 고민했어야 했다. 그래서 복사생성자가 나왔다.
84~89] 아래 캐스트의 차이점
값 캐스트 | 개체의 캐스트 | |
static_cast | 이진수가 변경된다. 값은 들어오는데, 형태마다 이진수 표기가 달라지므로 이진수가 변경됨. |
class Animal{ const char* getName() const; // 포인터 뒤에 있으므로 4바이트 뒤에 생성됨 priavate: char* mName; } class Cat : public Animal{ const char* getName() const; // 포인터 뒤에 있으므로 4바이트 뒤에 생성됨 priavate: char* mName; } class Dog: public Animal{ const char* getAddress() const; // 인트 뒤에 있으므로 4바이트 뒤에 생성됨 priavate: char* mAddress; } [개체의 캐스트] Animal* dog = new Dog(); // Animal 에서 Cat 으로 변환가능 ( 상속관계이므로 ) Cat dogToCat= static_cast<Cat*> dog; dogToCat . getAddress() ; // getName ()이 호출된다. 4바이트 뒤에있는 주소값을 반환하는데, 고양이의 이름이 출력되버린다. 다른 클래스로 변경했었다면 정말 괴랄해졌을뻔. |
reinterpret_cast | 이진수 값이 변환되지 않는다. ex) int a = -10; unsigned int *b = reinterpret_cast< unsigned int *> (a) ; //-10의 이진수가 저장되어 있는 힙메모리를 가리키는 unsigned 포인터를 만든다. //결과는 2의보수로 되어있는 이진수 그자체를 양의 10진수 숫자로 읽어들인다. |
연관없는 포인터 끼리의 형 변환 포인터와 포인터 아닌 일반 값의 변환 |
const_cast<> | 형변환을 불허한다. | const 를 떼어낼때 사용한다. |
전역변수 절때 쓰지말아라. 모든건 개체로 해라.
전역변수는 한번 선언해두면, 어디서나 접근할 수 있는 그런것이었으나.
이제는 어디서나 접근 할 수 있는 그런것은 아니다.
단지, 런타임 동안 "단 한개의 변수"만 있는 놈이다.