상속은 is-a관계
ex) 자동차는 탈것이다.(Car is a Vehicle).
has-a관계는 상속으로 모델링하면 안된다~
ex) 도서관은 책을 가지고 있다.
has-a관계는 하나의 클래스 안에 다른 클래스의 객체를 포함시키면 된다.
생성자 호출 순서: 부모 -> 자식
소멸자 호출 순서: 자식 -> 부모
자식클래스의 생성자(): 부모클래스의생성자()
{
...
}
childclass obj;
obj.parentclass::method() ;
객체들의 타입이 다르면 똑같은 메시지가 전달되더라도 서로 다른 동작을 하는 것을 말한다.
class Animal
class Dog : public animal
class Cat : public animal
인 상황에서
Dog dog;
Animal* pa;
pa = &dog;
이게 될까?
된다. 자식 클래스 객체는 부모 클래스 객체를 포함하고 있기 때문에 자식 클래스 객체는 부모 클래스 객체이기도 하다.
-상향 형변환(up-casting)을 하면 부모 클래스로부터 상속받은 부분만 포인터를 통해 사용할 수 있다.
Animal* pa = new Dog();
Dog* pd = (Dog*)pa;
부모 클래스 포인터 변수는 자식 클래스 객체를 참조할 수 있다. 역은 성립하지 않는다.
함수의 매개 변수는 자식 클래스보다는 부모 클래스 타입으로 선언하는 것이 좋다.
class shape{
public:
int b;
virtual void repr(){
cout << "hello" << endl;
}
};
class circle : public shape{
public:
int a;
void repr(){
cout << "1231231" << endl;
}
};
shape* ptr = new circle();
ptr->repr() ; -> hello , circle의 함수가 실행된다.
virtual 키워드는 멤버 함수에만 사용할 수 있다.(멤버 변수에 사용 X)
Binding
ex ) 변수의 데이터 타입이 무엇인지 정해지는 것
출처: https://secretroute.tistory.com/entry/140819 [Empty]
함수 호출을 실제 함수의 몸체와 연결하는 것을 바인딩이라고 한다.
정적 바인딩 - 컴파일 단계에서 모든 바인딩이 완료되는 것. 속도가 빠름
동적 바인딩(가상함수) - 바인딩이 실행(runtime) 시까지 연기되고 실행 시간에 실제 호출되는 함수를 결정하는 것. 속도가 느림
가상함수는 v-table이라고 불리는 테이블에 의하여 구현
circle 객체는 내부에 shape에 해당되는 부분과 circle에 해당되는 부분을 가지게 된다.
객체 안에서 가상 함수가 정의되면 각각의 객체는 이들 가상 함수를 관리하는 테이블을 만들게 된다. 객체가 생성되어서 shape부분이 생성되면 가상 함수 테이블은 shape안의 멤버들의 주소를 가지게 된다. 이어 circle부분이 추가로 생성되어 가상 함수가 재정의 되면 circle안의 멤버 함수 주로소 테이블의 내용이 변경된다.
virtual 반환형 함수이름(매개변수) = 0;
virtual 반환형 함수이름(매개변수){
...
}
가상함수와는 다르다.
순수 가상 함수를 하나라도 가지고 있는 클래스를 추상 클래스(abstract class)라고 한다.
주의할 점.
부모 클래스가 추상 클래스이기 때문에 부모 클래스로는 객체를 생성할 수 없다.
다만 포인터 변수는 생성할 수 있고 이 포인터 변수를 통해 자식 클래스의 객체를 가리킬 수 있다.
추상 클래스를 상속받으면 추상 클래스에 포함된 모든 가상 함수를 구현하여야한다.
클래스가 추상 클래스에 있는 하나의 가상 함수라도 빠뜨린다면 컴파일러는 해당 클래스도 추상 클래스로 정의되어야한다고 알린다.