언리얼/언리얼 C++

언리얼 C++ - 인터페이스

monstro 2024. 6. 30. 03:08
728x90
반응형

이번 포스트에서는 언리얼 C++이 일반적인 C++과 다른 차이점 중 하나인 인터페이스에 대해 알아보겠습니다.

 

1) 인터페이스란?

인터페이스는 다음과 같이 설명할 수 있습니다.

 

  • 객체가 반드시 구현해야 할 행동을 지정하는 데 활용되는 타입
  • 다형성의 구현, 의존성이 분리된 설계에 유용하게 활용
  • 의존성을 분리함으로써 클래스 간의 종속성을 낮춤

이러한 인터페이스는 추상클래스와 비슷하게 보일 수 있지만, 

추상 클래스에서는 불가능한 다중 상속이, 인터페이스에서는 허용되는 등의 분명한 차이점이 존재합니다.

그리고 이러한 인터페이스는 C++에서는 제공되지 않지만, 

더 최신화된 객체지향 언어인 Java나 C# 등에서는 제공되는 기능이기도 합니다.

 

2) 언리얼 C++ 인터페이스의 특징

정리하면 다음과 같습니다.

 

(1) 언리얼 엔진에서 인터페이스는 2개의 클래스로 구성됩니다.

 

U로 시작하는 타입 클래스와 I로 시작하는 인터페이스 클래스인데,

전자는 클래스 타입정보를 제공하고 후자는 실질적인 설계 및 구현을 담당합니다.

따라서 설계자는 후자인 인터페이스 클래스만 신경써주시면 됩니다.

 

(2) 추상타입으로만 선언할 수 있는 Java나 C#과는 다르게 언리얼 C++의 인터페이스는 구현이 가능합니다.

이를 통해 인터페이스에서 기본적으로 해야 하는 동작을 만들어 줄 수 있습니다.

 

3) 인터페이스의 사용

간단한 예제를 통해 인터페이스를 활용해보겠습니다.

사용할 클래스들의 관계는 다음과 같습니다.

 

 

Summon() 메서드를 사용하는 Archer클래스와 Warlock클래스는 

UndefinedPlayer뿐만 아니라, SummonInterface라는 인터페이스로부터도 상속을 받게 됩니다.

이러한 다중 상속에 거부감이 들 수 있지만,

인터페이스는 행동만을 지정하므로 클래스간의 결합을 강하게 만들지 않습니다.

따라서 다중 상속으로 인한 문제점을 일으키지 않습니다.

 

그에 반해 Summon() 메서드를 사용하지 않는 Warrior 클래스는 

UndefinedPlayer에게서만 상속을 받게 됩니다.

 

4) 인터페이스의 구현

 

기본적인 UndefinedPlayer 클래스의 구조입니다.

Name은 상속되어야 하므로 Protected로 접근설정을 하였고 이를 위해 게터와 세터를 만들었습니다.

 

 

인터페이스인 SummonerInterface에서는 순수가상함수인 Summon()을 선언하였습니다.

이때 선언은 I 인터페이스 클래스에서 이뤄져야 합니다.

 

 

인터페이스를 사용하기 위해서는 인터페이스로부터 상속이 이루어져야 합니다.

따라서 Archer 클래스를 위와 같이 구성하였고 Summon() 메서드에 override 키워드를 사용해 

오버라이드가 이뤄지지 않으면 에러를 발생하게끔 구성하였습니다.

 

 

이는 Warlock 클래스도 마찬가지이며 동일하게 설계하였습니다.

 

 

Warrior 클래스는 인터페이스를 사용하지 않으므로 AUndefinedPlayer에서만 상속받게끔 하였습니다.

 

 

이 모든 것들을 시험할 TestGameInstance에서는

UndefinedPlayer로부터 상속된 클래스들을 보관할 TArray를 만들었습니다.

전방선언을 통해 .h(헤더파일)에 불필요한 메모리가 사용되지 않게 하였습니다.

 

 

cpp 파일은 위와 같이 구성됩니다.

 

그리고 위의 코드를 빌드한뒤 언리얼 에디터에서 실행하면

 

위와 같은 결과를 얻을 수 있습니다.

 

5) 정리

인터페이스는 클래스가 반드시 구현해야 할 기능을 지정하는 데 사용합니다.

 

C++은 다중상속을 지원하지만, 무분별한 다중상속은 클래스간의 의존성을 높여 유지보수의 불편함을 초래합니다.

그러나 언리얼 C++의 인터페이스는 축소된 형태의 다중상속을 이끌어내어 C++이 갖는 단점을 극복하였습니다.

 

뿐만 아니라, 필요하다면 인터페이스에 구현을 통해 기본적으로 실행해야 하는 기능도 명시해줄 수 있습니다.

 

이렇듯, 언리얼 C++ 인터페이스를 통해 

 

클래스가 실행할 의무를 명시적으로 지정하면 좋은 객체 설계를 만드는데 도움을 얻을 수 있습니다.

728x90
반응형