C++
[C++] 상속, 생성자/소멸자 호출 순서, 다형성, 정적/동적 바인딩, 가상 소멸자
imagineer_jinny
2022. 3. 9. 23:15
본 내용은 POCU COMP3200: C++ 언매니지드 프로그래밍 강의를 토대로 작성하였습니다.
- 상속
- 다른 클래스의 특성들을 내려 받음
- 베이스(base) 클래스
- 부모 클래스
- 파생(derived) 클래스
- 자식 클래스
- 베이스(base) 클래스
- 파생 클래스의 개체는 다음 것들을 가짐
- 베이스 클래스의 멤버 변수
- 베이스 클래스의 멤버 메서드
- 자신의 생성자와 소멸자
- 파생클래스는 멤버 변수 및 메서드 추가가능
- 다른 클래스의 특성들을 내려 받음
- 파생 클래스의 접근 제어자
- Java와 달리 상속 시 베이스 클래스 멤버의 접근수준을 결정할 수 있다
- public 상속
- private 상속
- protected 상속
- Java와 달리 상속 시 베이스 클래스 멤버의 접근수준을 결정할 수 있다
- 생성자 호출 순서
- 베이스 클래스의 생성자가 먼저 호출 됨
- 명시적 또는 암시적으로
- 그 다음으로 파생 클래스의 생성자가 호출 됨
- 부모 클래스의 특정 생성자를 호출 할 때는 초기화 리스트를 사용해야 함
- 베이스 클래스의 생성자가 먼저 호출 됨
- 소멸자 호출 순서
- 생성자 호출순서와 정반대
- 파생 클래스 소멸자의 마지막에서 베이스 클래스의 소멸자가 자동적으로 호출됨
- 다형성(Polymorphism)
- 오버라이딩
- 말을 하는 행위는 어느 Animal이나 있다. 단, 실제 무슨 말을 하는지는 자식 클래스가 결정하게 하자
- 가상함수(다형성의 핵심)
- 자식 클래스의 멤버 함수가 언제나 호출됨
- 부모의 포인터 또는 참조를 사용중이더라도
- 동적(dynamic) 바인딩/ 늦은(late) 바인딩
- 실행 중에 어떤 함수를 호출할지 결정한다
- 당연히 정적 바인딩보다 느림
- 이를 위해 가상테이블이 생성됨
- 모든 가상 멤버 함수의 주소를 포함
- Q: 클래스 마다 하나 vs 개체마다 하나?
- A: 클래스 마다 하나!!!
- 개체를 생성할 때, 해당 클래스의 가상 테이블 주소가 함께 저장됨
- 자식 클래스의 멤버 함수가 언제나 호출됨
- 가상 소멸자
- 비 가상 소멸자
- 소멸자가 가상함수가 아님
코드 샘플 : Animal, Cat, Dog의 가상함수
Animal.h
#pragma once
namespace samples
{
class Animal
{
public :
Animal(int age);
virtual ~Animal();
virtual void Move() const;
virtual void Speak() const;
int GetAge() const;
private:
int mAge;
};
}
Cat.h
#pragma once
#include "Animal.h"
namespace samples
{
class Cat : public Animal
{
public:
Cat(int age);
virtual void Move() const;
virtual void Speak() const;
};
}
Animal.cpp
#include <iostream>
#include "Animal.h"
namespace samples
{
Animal::Animal(int age)
: mAge(age)
{
}
Animal::~Animal()
{
}
void Animal::Move() const
{
std::cout << "An animal is moving" << std::endl;
}
void Animal::Speak() const
{
std::cout << "An animal is speaking" << std::endl;
}
int Animal::GetAge() const
{
return mAge;
}
}
Cat.cpp
#include <iostream>
#include "Cat.h"
namespace samples
{
Cat::Cat(int age)
: Animal(age)
{
}
void Cat::Move() const
{
std::cout << "A cat is moving" << std::endl;
}
void Cat::Speak() const
{
std::cout << "Meow " << std::endl;
}
PolymorphismExample.cpp
#include "Animal.h"
#include "Cat.h"
#include "Dog.h"
#include "PolymorphismExample.h"
namespace samples
{
void PolymorphismExample()
{
Animal* cat = new Cat(3);
Animal* dog = new Dog(5);
cat->Move();
cat->Speak();
dog->Move();
dog->Speak();
delete cat;
delete dog;
}
}
그래서 다형성이 뭐라고? (면접문제 많이 나옴!!)