다중상속

김대익·2022년 3월 7일
post-thumbnail

base클래스가 1개만 있는 경우 선형(linear)적인 상속이라고 한다

(아래에서 위로 올라가면 하나밖에없다)


이렇게 여러 개의 base 클래스를 갖는 경우를 다중상속이라 한다.

#include <iostream>
class Animal
{
public:
	Animal(){
		std::cout << "Animal constructor" << std::endl;
	}
	virtual void speak()
	{
		std::cout << "Animal!" << std::endl;
	}
	virtual ~Animal(){
		std::cout << "Animal destructor" << std::endl;
	}
private:
	double animalData;
};

class Lion : virtual public Animal
{
public:
	Lion(){
		std::cout << "Lion constructor" << std::endl;
	}
	virtual void speak()
	{
		std::cout << "Lion!" << std::endl;
	}
	virtual ~Lion(){
		std::cout << "Lion destructor" << std::endl;
	}
private:
	double lionData;
};
class Tiger : virtual public Animal
{
public:
	Tiger(){
		std::cout << "Tiger constructor" << std::endl;
	}
	virtual void speak()
	{
		std::cout << "Tiger!" << std::endl;
	}
	virtual ~Tiger(){
		std::cout << "Tiger destructor" << std::endl;
	}
private:
	double tigerData;
};
class Liger : public Tiger, public Lion
{
public:
	Liger(){
		std::cout << "Liger constructor" << std::endl;
	}
	void speak() override
	{
		std::cout << "Liger!" << std::endl;
	}
	~Liger(){
		std::cout << "Liger destructor" << std::endl;
	}	
private:
	double ligerData;
};

int main()
{
	Liger liger;
	return 0;
}

여기서 class Liger : public Lion, public Tiger
Lion과 Tiger의 순서에 따라 생성자와 소멸자가 불러와지는 순서가 달라진다.

그리고 liger.speak();를 실행해보면


liger의 크기를 보면 40bytes가 나오는데

64bits컴퓨터이므로 포인터는 8bytes,
lion과 tiger과 liger의 double 변수 8bytes이므로 총 40bytes가 나온다.


Lion포인터를 이용해 Lion * polyLion = new Liger();를 생성하고
polyLion->speak();
delete polyLion;을 실행하면 Liger를 출력하는데

new Liger()로 liger 객체를 만들지만 Lion 포인터로 인해 빨간색으로 칠한 Lion 객체 부분만 볼 수 있고
가상테이블 주소를 저장하는 포인터가 speak()함수를 가지고 있는 Liger 가상테이블을 가리키기 때문이다.

만약 Liger * polyLion = new Liger(); Liger포인터에 Liger를 할당하면
Liger포인터는 객체 전부를 볼 수 있다


이 때 Lion, Tiger객체의 포인터는 모두 Liger 가상테이블을 가리킨다.

0개의 댓글