본문 바로가기
Programming/c++ Design Pattern

[C++] 추상 클래스

by 드가보자 2023. 11. 29.

추상 클래스(Abstract class)는 순수 가상 함수가 하나 이상 있는 Class를 말한다. 

class Shape
{
public:
	virtual void draw() = 0; 					 
};

class Rect : public Shape
{
public:
	void draw() override {
	}
};

int main()
{
	Shape  s; // error
	Shape* p;  
	Rect  r;
}

 

위 예시에서 class Shape 같은 경우가 추상 클래스라고 볼 수 있다.

추상클래스는 직접 객체를 생성할 수 없는데, 그 이유는 추상클래스는 구현이 완벽하지 않기 때문이다.

순수 가상함수처럼 -> 구현을 파생 클래스가 할 수 있도록 지시하는 역할을 하지, 그 자체로서 구현이 있지는 않기 때문이다.

 

추상 클래스는 Pointer 변수는 생성 가능하다. 

=> 객체를 직접 생성할 수는 없지만, 포인터를 통해서 파생 클래스의 객체를 가리킬 수 있다.

=> 추상 클래스의 주된 용도 중 하나인 다형성을 지원하기 위한 것.

 

객체 지향 설계가 지향하는 대표적인 이론이 하나 있다. 바로 OCP인데 Open Close Principle이다.

기능 추가에는 열려 있고, 코드 수정에는 닫혀 있어야된다.

 

#include <iostream>
struct ICamera 
{
	virtual void take() = 0; 
	virtual ~ICamera() { std::cout << "나 소멸됨" << std::endl; }
};

class People
{
public:
	void use_camera(ICamera* p) { p->take(); }
};


class Camera : public ICamera
{
public:
	void take() override { std::cout << "Take Picture" << std::endl; }
};

class HDCamera : public ICamera
{
public:
	void take() override { std::cout << "Take HD Camera Picture" << std::endl; }
};

class UHDCamera : public ICamera
{
public:
	void take() override { std::cout << "Take UHD Camera Picture" << std::endl; }
};

int main()
{
	People p;
	Camera c;
	p.use_camera(&c);

	HDCamera hc;
	p.use_camera(&hc);

	UHDCamera uhc;
	p.use_camera(&uhc);
}

 

여기서 Interface 와 추상 클래스의 차이점을 알아봐야하는데

일반적으로 추상 클래스와 Interface는 사람들이 동일한 의미로 많이들 사용한다고 한다.

 

추상 클래스 -> 순수 가상함수 + 최소한 하나 이상의 멤버 변수

 

인터페이스 -> 순수 가상함수로만 이루어진 경우

 

여기서는 struct Icamera가 순수 가상함수로만 이루어져 , Interface 역할을 한다.

 

class로 두어도 상관없지만 , Struct로 하는 이유는 public: 한 줄을 안 적어도 되기 때문인데

Struct는 Default 접근 제어가 public이기 때문이다. 

어차피 virtual function은 접근이 가능해야 하기 때문에 struct로 만드는 것이 간결하다.

 

Camera로 사진을 찍는게 목표인데, 카메라의 종류가 일반 Camera도 있고, HD Camera도 있고, UHD Camera도 있고 등등 다양한데 Icamera라는 Interface를 사용한다면

 

3년 뒤에 새로운 카메라 FHD Camera가 나와도, Interface 코드 수정은 안해도 되고 새로운 FHD에 대해서 구현만 해주면된다. => 되게 간결하고 유지 보수가 쉽다. 

 

여기서 강한 결합이랑 약한 결합이라는 개념이 있는데

 

  1. 강한 결합(tightly coupling) 
    만약 People Class에 (ICamera* p) 대신 (Camera*p) 를 사용했더라면 이 사람은 Camera 만 사용하겠다고 생각할 수 있다. HD Camera나 UHD Camera를 사용하기 위해서는 또 결국 함수를 만들어야 된다는 문제점이 발생한다.
    => 결과적으로는 나쁜 Desgin , People과 Camera끼리 강력하게 묶인 , 그 외의 것들은 사용을 고려하지도 않는 
    나쁜 Coding Style

  2. 약한 결합(loosely coupling)
    하나의 클래스가 다른 클래스 사용 시에 클래스 이름을 직접 사용하지 않고, Interface를 사용하는 경우
    확장성이 있고 유연한 Design -> 위 코드의 예시 같은 경우가 Loosely Coupling이라고 생각할 수 있는 것이다. 

'Programming > c++ Design Pattern' 카테고리의 다른 글

[c++ Design Pattern] Template Method  (0) 2023.11.29
[C++] OCP Code 예제  (1) 2023.11.29
[C++] 가상 함수  (1) 2023.11.28
[c++] Upcasting  (0) 2023.11.28
c++ 생성자  (0) 2023.11.28