C++/C++

[C++] 가상함수

메카인 2023. 2. 7. 19:27

◆C++는 클래스의 멤버함수를 실행할 경우, 클래스 인스턴스의 현재 타입을 기준으로 실행할 멤버 함수를 기계적으로 정해버립니다. 따라서 형변환이 되었을 경우 오버라이딩이 제대로 작동하지 않을 수 있습니다.

//ex
class car{
    int tier;
    car(){
    	tier=4;
    }
    void printInfo(){
    	printf("%d개의 타이어가 있습니다.",tier);
    }
};
class motorcycle : public car{
    int tier;
    motorcycle(){
    	tier=2;
    }
    void printInfo(){
    	printf("%d륜 오토바이 입니다.",tier);
    }
};

int main(){
	motocycle* cycle = new motocycle();
    car* cart = cycle;
    
    //cart의 멤버변수 printInfo가 실행되어 4개의 타이어 출력
    cart->printInfo();
    //motocycle 멤버변수 printInfo가 실행되어 2륜 오토바이 출력
    cycle->printInfo();
    
    //같은 객체를 가지지만 서로 다른 printInfo가 출력됨
    
    return 0;
}

 

◆가상함수(virtual)

▷오버라이딩 할 때, 부모 클래스의 함수에서 virtual 키워드를 추가하게 되면 정상적으로 우리가 원하는 오버라이드된 함수를 찾아서 실행하게 됩니다. (실제 내용의 맞는 클래스의 멤버함수 실행

▷자바의 경우 자동으로 virtual이 적용됩니다.

 

◆소멸자에서의 virtual 

▷소멸자에 virtual 키워드를 넣지 않게 되면, 상속받은 클래스일 경우 클래스의 현재 타입에 맞는 소멸자만 호출하게 된다.

▷자식 클래스의 소멸자일 경우 부모 클래스 까지 연쇄 삭제 되지만, 반대의 경우는 메모리 누수가 발생하기 때문에 소멸자에 virual 키워드를 쓰는것을 권장한다.

 

※클래스 소멸자를 작성할 때 클래스를 동작하면서 만들어준 멤버를 delete를 통해 힙에서 제거 해주어야 한다.

 

◆C#은 virtual과 override를 사용한다.  (가상함수를 사용할때 override 사용해야함)


-> 과 . 의 차이

▷ . 은 클래스의 멤버를 직접 접근합니다. 

▷ ->은 포인터를 통해 멤버를 접근합니다. (동적 할당 된 멤버변수에 접근할 때 필요한듯 하다.)(정확히 모르겠다)

 

◆접근 제한자를 작성하지 않으면 접근 제한자가 private로 된다.