C++(따라하며 배우는 C++)

Chapter 12-7, 8. 순수 가상 함수, 추상 기본 클래스, 인터페이스 클래스, 다이아상속문제

void_melody 2021. 11. 3. 23:47

부모 클래스에 가상 함수를 body가 없는 상태로 선언만 해놓은 형태를 pure virtual function이라 한다.

pure virtual function이 단 하나라도 있으면, 추상 클래스가 되기 때문에, 당연히 객체를 생성할 수 없다.

이럴 경우, 의미 자체가 자식 클래스들에서 해당 함수를 구현한다는 의미.

자식 클래스에서 해당 virtual 함수를 구현하지 않았기에, 자식 클래스의 객체를 만들 수 없다.

자식 클래스에서 해당 함수를 구현하니, 정상적으로 작동.

pure virtual function을 선언하는 이유는 간단하다.

자식들이 해당함수를 구현해 각자에 맞게 사용할 수 있게 하기 위함.

이러한 pure virtual function들로만 이루어진 부모 클래스를 '인터페이스 클래스'라 부른다.

왜 인터페이스일까?

부모클래스의 있는 함수들을 각자의 자식들이 구현을 해놨을 것이고, 해당 자식 객체에 맞게 사용할 수 있기 때문이다.

#include <iostream>
using namespace std;

class PoweredDevice
{
public:
	int m_i;

	PoweredDevice(int power)
	{
		cout << "PoweredDevice : " << power << '\n';
	}
};

class Scanner : public PoweredDevice
{
public:
	Scanner(int scanner, int power)
		: PoweredDevice(power)
	{
		cout << "Scanner : " << scanner << '\n';
	}
};

class Printer : public PoweredDevice
{
public:
	Printer(int printer, int power)
		: PoweredDevice(power)
	{
		cout << "Printer : " << printer << '\n';
	}
};

class Copier : public Scanner, public Printer
{
public:
	Copier(int scanner, int printer, int power)
		: Scanner(scanner, power), Printer(printer, power)
	{}
};

int main()
{
	Copier cop(1, 2, 3);

	cout << &cop.Scanner::PoweredDevice::m_i << endl;
	cout << &cop.Printer::PoweredDevice::m_i << endl;
}

 

현재 객체 상속이 이러한 구조이기 때문에 scanner가 가지는 m_i와 printer가 가지는 m_i는 독립적이다.

#include <iostream>
using namespace std;

class PoweredDevice
{
public:
	int m_i;

	PoweredDevice(int power)
	{
		cout << "PoweredDevice : " << power << '\n';
	}
};

class Scanner : virtual public PoweredDevice
{
public:
	Scanner(int scanner, int power)
		: PoweredDevice(power)
	{
		cout << "Scanner : " << scanner << '\n';
	}
};

class Printer : virtual public PoweredDevice
{
public:
	Printer(int printer, int power)
		: PoweredDevice(power)
	{
		cout << "Printer : " << printer << '\n';
	}
};

class Copier : public Scanner, public Printer
{
public:
	Copier(int scanner, int printer, int power)
		: Scanner(scanner, power), Printer(printer, power),
		PoweredDevice(power)
	{}
};

int main()
{
	Copier cop(1, 2, 3);

	cout << &cop.Scanner::PoweredDevice::m_i << endl;
	cout << &cop.Printer::PoweredDevice::m_i << endl;
}

 

그렇기에 상속을 virtual로 받게 된다면, 하나로 받는 형태이다. 그렇기에 현재 두 개의 m_i가 같은 주소값을 나타낸다.