dynamic_cast 동적 캐스트(dynamic_cast)는 실행 중에 형변환을 판단한다. 포인터 또는 참조 형을 캐스팅할 때만 사용할 수 있다. 호환되지 않는 자식으로 캐스팅 하려고 하면 NULL을 반환한다. dynamic_cast가 static_cast보다 안전하다 // C style Animal *myPet = new Cat(); Dog *myDog = (Dog *)myPet; // 컴파일 가능 myDog->getHouseName(); // 컴파일 되지만 Undefined Behavior // C++ style Animal *myPet = new Cat(); Dog *myDog = dynamic_cast(myPet); // 컴파일 되지만, NULL을 반환한다. // 컴파일 되지만 실행되지 않는다...
Language
const_cast const_cast의 사용은 피하는 것이 좋다. // C style void Foo(const Animal *ptr) { Animal *animal = (Animal*)ptr; animal->SetAge(5); } // C++ style void Foo(const Animal *ptr) { Animal *animal = const_cast(ptr); animal->SetAge(5); } const_cast는 자료형을 바꿀 수 없으며, 오로지 const 또는 volatile 어트리뷰트를 제거할 때 사용된다. Animal *myPet = new Cat(2, "Coco"); const Animal *petPtr = myPet; // C style Animal *myAnimal1 = (Ani..
가장 위험한 캐스팅은 reinterpret_cast로, 이 때문에 static_cast가 도입되었다고 해도 과언이 아니다. // C style unsigned int myPetAddr = (unsigned int)myPet; // C++ style unsigned int myPetAddr = reinterpret_cast(myPet); reinterpret_cast는 연관 없는 두 포인터 형 사이의 변환을 허용한다. Cat* ↔ House* char* ↔ int* 또한 포인터와 포인터 아닌 변수 사이의 형 변환을 허용한다. Cat* ↔ unsigned int 하지만 주의해야 할 점은 이진수 표기는 달라지지 않는다. int의 이진수를 unsigned int로 해석할 뿐이므로, 부호 등의 정보는 유지되지 않..
1. 값 두 숫자 자료형의 변환 값을 유지하려고 한다. 이진수 표기는 달라질 수 있다. 예시: float ↔ int 2. 개체 포인터 변수형 체크 후 부모 클래스를 자식 클래스로 변환다. 컴파일 시에만 체크할 수 있다. (정적) 실행 중에 크래시가 날 수 있다. Animal* myPet = new Cat(2, "Coco"); Cat* myCat = static_cast(myPet); Dog* myDog = static_cast(myPet); myDog->GetDogHouseName(); Dog* myCat = static_cast(myPet); 컴파일은 된다. 컴파일러는 Animal과 Dog가 상속 관계임을 확인한다. 실행 중에 크래시가 날 수 있다. Dog 클래스의 멤버를 가지고 있지 않기 때문이다...
암시적 캐스팅 (Implicit Casting) 컴파일러가 형을 변환해 준다. 형변환이 허용되고 프로그래머가 명시적으로 형변환을 하지 않은 경우에 발생한다. 명시적으로 변환한 경우 컴파일러는 개입하지 않는다.. int num1 = 3; long num2 = num1; 명시적 캐스팅 (Explicit Casting) 프로그래머가 형 변환을 위한 코드를 직접 작성하는 것이다. C++에서는 다음 네 가지 캐스팅을 제공한다. static_cast const_cast dynamic_cast (C++98, modern C++) reinterpret_cast C 스타일 캐스팅 int score = (int)someVariable; 위의 C++ 캐스팅 네 가지 중 하나의 기능을 수행한다. 그러나 명확하지 않고 실수를 ..
인터페이스(Interface) CPP에서 공식적으로 지원하는 기능은 아니다. 클래스 앞에 ‘I’ 를 붙여 인터페이스임을 표시한다. 음절 뒤에 able을 넣어주는 것이 좋다. Format 특징 추상 클래스와 매우 비슷하다. 자체적으로 인터페이스를 지원하지 않는다. 순수 추상 클래스 순수 가상 함수만 존재한다. (멤버 변수가 없다) 다중 상속의 문제점을 피해간다.
구체 클래스 함수의 구현체가 있는 클래스 추상 클래스 구현이 되어있지 않은 함수(순수 가상 함수)를 가진 클래스 // Animal.h class Animal { public: virtual ~Animal(); virtual void Speak() = 0; // 구현하지 않겠다는 의미. 순수 가상 함수라고 불린다. private: int mAge }; //Cat.h class Cat : public Animal { public: ~Cat(); void Speak(); private: char *mName; }; → Animal은 추상 클래스이고 Cat은 구체 클래스이다. 순수 가상 함수 구현체가 없는 멤버 함수 파생 클래스가 구현해야 한다. virtual void Speak() = 0; 이 함수를 구현하지..
다중 상속 다중 상속은 사용하지 않는 것이 일반적이다. 생성자 호출 순서 파생 클래스에서 등장한 부모 클래스 순서대로 호출된다. 초기화 리스트의 순서는 상관 없다. → super()를 사용할 수 없는 이유는 다중 상속이 가능하기 때문입니다. 문제점1: 같은 이름의 함수 같은 이름의 함수가 있다면 호출될 함수를 명시적으로 지정해야 한다. > 어떤 함수를 호출해야하는지 모호하다면 컴파일이 안 되기 때문에 부모클래스를 특정해주어야 한다. 문제점2: 다이아몬드 문제 Liger는 몇 개의 2개의 Animal 클래스를 동시에 가지게 되는 문제가 발생. 다이아몬드 문제(Diamond Problem): 다중 상속을 사용할 때, 한 클래스가 두 개 이상의 클래스를 상속하고 그 두 클래스가 다시 같은 클래스를 상속하는 ..