C & C++/개념(Concept)

C/C++ 개념: 완전한 타입(Complete Type), 불완전한 타입(Incomplete Type)

kim선달 2020. 11. 11. 23:31
Select Language

 

완전한 타입(Complete Type), 불완전한 타입(Incomplete Type)


1. 설명

완전한 타입이란, 해당 컴파일 시점에서 그 타입(구조체(struct), 열거자(enum), 공용체(union), 클래스(class))의 구현(Implement) 정보를 모두 알고 있는 타입을 말합니다.

위 4가지를 제외한 모든 타입은 무조건 완전한 타입입니다.

 

불완전한 타입이란, 해당 컴파일 시점에서 그 타입의 구현 정보를 알지 못하고, 선언된 정보만 알고 있는 상태를 말합니다.

 

※ 타입의 어떠한 정보도 알지 못하는건 그냥 알수 없는 타입(unknown type)이나 알수 없는 식별자(unknown identifier) 입니다. 보통 실수로 헤더를 넣지 않거나 했을 때 생깁니다.

 


2. 예시

#include <stdio.h>

struct Widget;

int main(){
  Widget w;

  return 0;
}

struct Widget {}; // 실제 구현은 여기서!

 

Widget 구조체를 전방 선언(forward declaration) 한 후, 바로 사용한다고 가정 해 봅시다.

컴파일러는 위에서 아래로 읽기 때문에, main() 안에서는 Widget 객체의 생성자에 대한 정보를 전혀 알 수 없습니다.

 

그래서 컴파일 하면 다음과 비슷한 에러가 나오며 실패하게 됩니다.

/Users/yonggyulee/CLionProjects/playground/main.cpp:6:10: error: variable has incomplete type 'Widget'
  Widget w;
         ^
/Users/yonggyulee/CLionProjects/playground/main.cpp:3:7: note: forward declaration of 'Widget'
class Widget;

 

이를 해결하려면, 구현을 실제 사용 시점 이전에 작성해야 합니다.

#include <stdio.h>

struct Widget;
struct Widget {};

int main(){
  Widget w;

  return 0;
}

 

 

※ 함수의 전방 선언(Function forward declaration)은 함수에 서명(signature)을 모두 담고 있으므로, 구현 이전에 호출해도 알맞은 용법입니다.

 


3. 예외

 

포인터는 해당 타입이 불완전 하더라도 선언할 수 있습니다.

#include <stdio.h>
#include <cstdlib>

struct Widget;
void initWidget(Widget** w);

int main(){
  Widget* w;
  initWidget(&w);

  return 0;
}

struct Widget {}; // 실제 구현은 여기서!

void initWidget(Widget** w) {
  // C
  *w = (Widget*) malloc(sizeof(Widget));
}

 

※ C 언어를 예시로 들었지만, C++ 에서도 동일하게 가능합니다.

불완전한 타입에 대한 포인터를 이용하는 디자인이 PImple 기법입니다.

'C & C++ > 개념(Concept)' 카테고리의 다른 글

C/C++ 개념: 전방 선언(forward declaration)  (0) 2020.11.12