티스토리 뷰

반응형
int main()
{
    Dog d;
    Dog*    p1 = &d; // ok
    int*    p2 = &d; // error
    Animal* p3 = &d; // ok... 기반 클래스 포인터로 파생 클래스 객체를 가리킬수 있다.
                     // upcasting. 객체지향의 중요한 특징
    // 1. 기반 클래스 포인터로 파생 클래스 객체를 가리킬수 있다.
    // 2. 그런데, 기반 클래스 포인터로 기반 클래스 멤버만 접근 가능
    p3->age = 10;
    p3->color = 10; // error. 컴파일 시간에는 무조건 p3를 Animal 이라고 생각하기 때문에
 
    // 3. Dog 고유 멤버에 접근하려면 캐스팅 필요
    static_cast<Dog*>(p3)->color = 10;
 
}

 

위의 코드처럼 기반 클래스(Animal) 포인터(p3)로 파생 클래스 객체(d)를 가리킬 수 있다. => upcasting의 개념

하지만, 기반 클래스 포인터로는 기반 클래스의 멤버만 접근이 가능하다. 

따라서, p3->color같은 경우는 dog의 어트리뷰트이기 때문에 error가 난다.

만약, Dog의 교유 멤버에 접근하려면 static_cast를 통해서 접근하는 방법이 있다.

 

static_cast<>, dynamin_cast<>

가상함수는 파생 클래스에서 재정의 될 것을 기대한다는 의미로 정의되는 함수 입니다.

 

class Animal 
{
public: 
    int age;
    virtual ~Animal() {}
};
class Cat : public Animal 
{
 
};
class Dog : public Animal
{
public:
    int color;
};
//
//void NewYear(Dog* pDog) // Dog 만 처리하는 함수
//{
//  
//}
 
void NewYear(Animal * p) 
{
    ++(p->age);
 
    // p->color = 10; // error
    
    Dog* pDog = static_cast<Dog*>(p);
    Dog* pDog = dynamic_cast<Dog*>(p);
 
    std::cout << pDog << std::endl;
 
    if (pDog != nullptr) {
        pDog->color = 10;
    }
}
int main()
{
    Animal a; NewYear(&a);
    Dog    d; NewYear(&d);
}

 

위 코드는 기반 클래스(Animal)의 소멸자를 가상 함수를 통해서 만들었다. 

또한, NewYear라는함수는 모든 동물을 처리할 수 있는 함수로 처리했다.

저 의미는 모든 동물의 공통 작업만 하겠다는 의도를 가지고 있다고 생각해도 된다.

 

하지만, 유지 보수중 p가 Dog라면 색상도 변경하고 싶을 때가 있다.

그럴 경우에는 casting을 통해서 해결 할 수 있다.

그 방법은 static_cast<>, dynamic_cast<> 두가지가 있다.

 

static_cast: 컴파일 시간 캐스팅. 빠르지만 p가 Dog를 가리키지 않아도 캐스팅이 된다는 단점이 있다.

dynamic_cast: 실행 시간 캐스팅. 느지만 p가 Dog를 가리키는 지 실행시간에서 조사를 하기 때문에 알 수 있다.

                          Dog를 가리키지 않는다면, 0을 반환한다.

 

 

 

728x90
반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함
250x250