본문 바로가기

카테고리 없음

c++ 포큐 정리

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 를 떼어낼때 사용한다.

 

전역변수 절때 쓰지말아라. 모든건 개체로 해라.

전역변수는 한번 선언해두면, 어디서나 접근할 수 있는 그런것이었으나. 

이제는 어디서나 접근 할 수 있는 그런것은 아니다.

단지, 런타임 동안 "단 한개의 변수"만 있는 놈이다.