본문 바로가기
C++

[C++] 상속, 생성자/소멸자 호출 순서, 다형성, 정적/동적 바인딩, 가상 소멸자

by imagineer_jinny 2022. 3. 9.

본 내용은 POCU COMP3200: C++ 언매니지드 프로그래밍 강의를 토대로 작성하였습니다.

 

  • 상속
    • 다른 클래스의 특성들을 내려 받음
      • 베이스(base) 클래스
        • 부모 클래스
      • 파생(derived) 클래스
        • 자식 클래스
    • 파생 클래스의 개체는 다음 것들을 가짐
      • 베이스 클래스의 멤버 변수
      • 베이스 클래스의 멤버 메서드
      • 자신의 생성자와 소멸자
    • 파생클래스는 멤버 변수 및 메서드 추가가능

 

 

  • 파생 클래스의 접근 제어자
    • Java와 달리 상속 시 베이스 클래스 멤버의 접근수준을 결정할 수 있다
      • public 상속
      • private 상속
      • protected 상속
  • 생성자 호출 순서
    • 베이스 클래스의 생성자가 먼저 호출 됨
      • 명시적 또는 암시적으로
    • 그 다음으로 파생 클래스의 생성자가 호출 됨
    • 부모 클래스의 특정 생성자를 호출 할 때는 초기화 리스트를 사용해야 함

 

  • 소멸자 호출 순서
    • 생성자 호출순서와 정반대
    • 파생 클래스 소멸자의 마지막에서 베이스 클래스의 소멸자가 자동적으로 호출됨

 

  • 다형성(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;
	}
}

 

 

그래서 다형성이 뭐라고? (면접문제 많이 나옴!!)

 

 

 

댓글