• Friends
  • in methods: can access private members

    • Class Friend: any method can access private and protected members
    class Tv; //선언해두어야 아래에서 사용 가능
    
    class Remote{
    	friend class Tv; //서로 friend 가능
    	friend class Tv2; //여러 클래스와 friend 가능
    public:
    	void set_channel(Tv&t, int c) { t.channel = c; } 
    	void set_channel2(Tv2 & t, int c);
    	//t.channel 접근 가능
    }
    
    class Tv{
    public:
    	friend class Remote; //어디에 선언되어도 상관 없음.
    private:
    	int channel;
    };
    
    class Tv2{
    public:
    	friend void Remote:set_channel(Tv2 &t, int c);
    	//friend member function사용 가능
    }
    
    inline void Remote::set_channel2(Tv2&t, int c) { t.channel = c; }
    
    
  • Nested Classes 클래스 내부에 클래스 선언 local definition

    class Queue
    {
    private:
    	class Node
    	{
    	public: //접근도 동일하게 적용! Queue에서 Node의 private 불가
    		int item;
    		Node(int i);
    	};
    };
    
    Queue::Node::Node(int i) { item = i; } //:: 두번 쓰기
    
  • Exceptions

    • #include <cstdlib> std::abort(); call abort: stop and terminate program(Aborted(core dumped))

    • try catch

      try{
      	z=func(x,y);
      }
      catch(const char* s){
      	cout << "error";
      }
      catch(...){} //default catch: 진짜 "..."을 사용
      ~
      int func(int x, int y){
      	if(condition) throw "not allowed"; 
      	//const char* 형식 throw
      	//함수 실행 종료
      }
      
      • throwing objects exception 할 때 정보도 같이 포함해서 던지기 위해 사용 throw 전용 클래스를 만든다.
      try{func(x,y);}
      catch(bad_func&ext){
      	cout <<"error";
      	ext.mesg();
      }
      ...
      func(int x, int y){
      	if(condition) throw bad_func(x,y);
      }
      
      class bad_func{
      private:
      	int x,y;
      public:
      	bad_func(int x_, int y_):x(x_), y(y_){}
      	void mesg(){ cout <<"error!!";}
      };
      
      
      • Unwinding call stack exception 발생 시, 호출된 함수를 전부 종료; 이때 각 함수들의 객체들이 전부 파괴 된다! 따라서 exception이 예상되면 이를 호출하는 스택에 있는 모든 함수에 try를 넣어주자.

      또한 throw 아래는 전부 생략되어 memory leak: 파괴자 호출하고(delete) 끝내기 //또는 스마트 포인터 사용

      Untitled

      Untitled

    • <exception> class

      • 예외 클래스 만들 때 부모 클래스로 사용 virtual member function what() 오버라이드 가능 what(): return string
      #include <exception>
      class bad_func: public std::exception
      {
      public: 
      	const char* what() {return "error";}
      };
      
      catch(std::bad_func& b){}
      catch(std::bad_func2& b2){}
      catch(std::exception& e){} 
      //이걸 먼저 쓰면 bad func와 bad func2 둘다 해당! 
      //부모를 나중에 쓰자.
      
    • <stdexcept> class

      • catch(std::(errorname)& s);
        • logic_error
          • domain_error : asin(-2) 등
          • invalid_argument : func(int x)에 func(”AB”)
          • length_error : not enough space
          • out_of_bounds : a(10), a[100]과 같이
        • runtime_error
          • range_error : a(10), a[i]에 i=10
          • overflow_error : int에 30억
          • underflow_error : 최소 소수점보다 작을 때
    • <new> class

      • bad_alloc : 할당에 문제 ex) int x[100000000000000000];
  • type cast operator (부모 클래스*)자식클래스 포인터 형변환: 가능 (자식 클래스*)부모클래스 포인터 형변환: 안전하지 못함.

    Untitled

    • dynamic_cast Type* pp = dynamic_cast<Type*>(ptr);

      • ptr이 가르키는 object가 Type이거나 Type의 자식 클래스면 작동
      • 아니면 nullptr 반환!!!!!
      • for reference var Type& pp = dynamic_cast<Type&>(ptr);
        • rb가 Type이거나 Type 자식이면 작동
        • 아니면 bad_cast 예외처리 발생! catch 필요.
    • const_cast 포인터나 참조형의 상수성(const)를 제거하는 데에 사용 형 변환은 불가능 Type* pp = const_cast<Type*>(ptr)

      Untitled

      만약 포인터가 가르키는 객체가 const라면 안 바뀜! 포인터의 상수성을 없애지, 객체의 상수성 없애는게 아님.

    • static_cast 그냥 형변환과 다를 것이 없으나, 형변환 에러를 컴파일 타임에 확인 (그냥 형변환은(c-style) 런타임 에러가 발생)

      • double, int
      • float, long
      • 등등 implicit cast 가능한 모든 것
    • reinterpret_cast 다른 포인터간의 변환, 수와 포인터간의 변환 가능 정수를 포인터로 바꾸면 해당 주소로 직접 이동함! 위험

      • 구조체와 포인터 간의 변환 등으로 씀

        Untitled