== 다양한 형태의 성질을 가지는것.동일한 종에 속하는 생물이라 할지라도 다양한 변이를 가지는 현상(카테고리는 같은데 하는 짓이 다른것)
Ex) 동물 카테고리 안 여러가지 동물이 있는데 공동된 특징은 움직임이다.근데 어떻게 움직이는지는 다 다르다.움직이기 위한 방법, 사용하는 신체부위 등이 다름.이렇게 내가 이동하라고 동일한 명령을 내리면 각각이 다른 행동을 한다. 이것을 “다형성”이라고 한다.
-> 이걸 코드에 적용하면 똑같은 형태인데 다른 결과같이 나오는것을 뜻한다.
C++ 언어에서의 다형성
-> 3가지만 기억하자.(가상함수, 함수템플릿, 함수 오버로드)
가상 함수
부모 클래스와 자식 클래스에 동일한 이름의 함수의 다른 작동
함수 템플릿(STL=Standard Templete Library)
동일한 이름의 함수가 다양한 자료형을 처리
함수 오버로드
동일한 이름의 함수가 다른 작동
연산자 오버로드
한가지 연산자가 다양한 작동
함수 이름이 같아도 다른 작업을 하는 것을 말한다.
예로 들어 클래스 A에 임의의 함수가 있는데 클래스 B가 클래스 A를 상속 받았고,클래스 B에도 동일한 이름의 임의의 함수가 있다고 가정할때
보통은 코드에 동일한 함수가 중복되면 오류가 나지만 근데 상속관계에선 함수가 이름이 같은걸 허용해준다.함수이름이 동일하다는 가정하에 클래스 A만의 함수가 있고,클래스 B만의 함수가 있는걸 예외적으로 인정해주겠다는것이다.
이런 특징이 적용된 함수를 “가상 함수”라 한다.
(==함수를 오버라이드 했다.!= 오버로드)
Ex)
A클래스에서 Func란 cout함수를 호출할 땐 A함수란 텍스트가 나오고
B클래스에서 Func란 cout함수를 호출할 땐 B함수란 텍스트가 나옴.
-> 결국 둘이 하는일이 다르다.
Virtual
부모클래스 앞에 붙는 키워드
부모클래스에서 어떤 함수 앞에 virtual 키워드를 붙히면 그 함수는 가상함수가 된다.(가상함수로 만들겠다는 키워드여서 곧 이 함수는 자식클래스에서 동일명으로 갖다쓸 수 있게하겠다는것이다.)
Override
자식클래스 뒤에 붙는 키워드
상속관계에서 부모 클래스의 가상 함수를 자식 클래스에서 쓴다고 했을때는 이 함수가 오버라이드 되었다고 생각하면된다.내가 부모 클래스의 함수를 쓰고싶으면 가상함수로 지정해주고 오버라이드해서 쓰면된다.
(클래스 간 이름이 같다? -> 이 경우임)
오버라이드는 프로그래머의 선택사항이다.
만약 B클래스에서 오버라이드된 함수를 정의하지않았다고하면 부모클래스의 함수를 가져와서 쓰게된다.(상속받았으니깐)
->버츄어는 자동이지만 오버라이드는 컴파일러가 자동으로 안붙혀줌
부모클래스에 A클래스에서 Func란 cout함수를 호출할 땐 A함수란 텍스트가 나오고 virtual을 붙여 가상함수가 되어있다해도 오버라이드함수를 꼭 만들 필요없다.(버츄얼은 진짜 오버라이드하기위해서 하는거 그이상 그이하도 아니다.)
만약 오버라이드를 붙였는데 버츄어가 없는 경우는 원래는 오류가 나야되는데 이 상황에서는 컴파일러가 알아서 버츄어를 붙여준다.
이 두 키워드가 쓰이는 이유는 부모 클래스와 자식 클래스가 붙어있는게 아니라 떨어진 경우 구분을 해주지않으면 다른 사람이 어떤 함수가 가상함수인지도 모르고 오버라이드가 된 함수가 있겠구나라고 생각을 못하니깐 구분을 해준것이다.
Virtual을 보는 순간 얘를 상속한 무언가가 밑에 어떤 클래스에 있겠네를 생각하자.
Override는 일반클래스에서는 못쓴다. 상속받은 부모클래스에서만 쓸 수 있다.(하지만 이것도 컴파일러가 자동으로 부모클래스에 버추어 붙여서 해결됨)
중괄호가 끝나면 엔터로 한 줄 공백 처리해주자.
가상 함수의 생성자 초기화(출력 ox)
-> 가상 함수 반환값 출력(가정)
-> 오버라이드된 함수의 생성자 초기화(출력 ox)
-> 오버라이드된 함수의 반환값 출력(가정)
-> 오버라이드된 함수 소멸자
-> 가상 함수 소멸자
이런 순서로 생각할 수 있는데 실제 결과는 특이점이 있다.
가상 함수의 생성자 초기화(출력 ox)
-> 가상 함수 반환값 출력(가정)
-> 추가)
오버라이드된 함수의 객체가 생성되기전에 부모의 객체 생성자가 생성
-> 오버라이드된 함수의 생성자 초기화(출력 ox)
-> 오버라이드된 함수의 반환값 출력(가정)
-> 오버라이드된 함수 소멸자
-> 추가)
자식 클래스가 선언되면서 추가로 불렸던 가상함수 생성자가 소멸됨
-> 첫번째의 가상 함수 소멸자가 불려서 소멸
왜 이렇게되냐?
자식클래스가 메인함수에서 객체가 생성될 때,부모클래스 객체 하나가 같이 추가로 생성이 된다.왜 생성이 되냐면 부모클래스를 상속받았다는게 변수와 함수들을 그대로 가져왔다는건데 여기서 그대로 가져오는 가장 쉬운 방법은 오버라이드 함수가 가상함수를 먹으면된다.(== 그냥 부모클래스 객체를 하나 생성하고 같이 데리고다닌다.)
그러면 상속받으면 부모클래스에 있던 함수가 다 불리는건가?
-> 생성자 함수는 객체가 선언되는 순간 자동으로 생성되는 특성이 있으니깐 생성자가 생성돼서 출력되는거고 부모클래스에 있던 다른 함수들은 자동으로 불리는게 아니라 따로 써줘야된다.그래서 출력상에는 부모클래스의 생성자의 초기화 내용 및 소멸자 내용만 추가로 생기는 것이다.
정리
클래스가 상속관계에 있을때, 메인함수에서 자식클래스 객체를 생성(선언)할땐 부모 객체 생성하고 자식 객체를 생성한다.(코드에선 안보이고 내부적으로만)이때 부모 객체가 생성된다는건 부모의 생성자가 불리고 그런다음 자식 생성자가 불린다.
소멸될때도 소멸은 생성의 역순이니깐 자식이 소멸하고 부모가 소멸한다.근데 자식 소멸 -> 부모 소멸 -> 부모 소멸인데 두번째의 부모 소멸은 자식 객체 선언될때 추가로 불린 부모의 객체를 소멸하는 것이다.그런다음에서야 첫번째 생성되었던 부모 객체를 소멸시키는 것이다.