Framework에 대한 정의를 내려 보려고 하니..참 막막하기는 하다...

Framework, Architecture 등 너무도 익숙하게 사용하는 용어라 정의하기가 더욱 어려운 것 같다.


google에서 Framework에 대한 정의를 찾아보면 20 여개 정도가 검색이 되는데 그중 아래의 정의가 일반적으로 우리가 생각하는 Framework이 아닐까 생각한다.


In software development, a Framework is a defined support structure in which another software project can be organized and developed. Typically, a framework may include support programs, code libraries and a scripting language amongst other software to help develop and glue together the different components of your project.


소프트웨어 프로젝트에서 활용할 수 있는 기반 구조로 일반적으로 지원 프로그램, 코드 라이브러리 등 프로젝트의 다양한 컴포넌트들을 개발하고 유기적으로 결합하기 위해 사용하는 소프트웨어를 말한다.

과거에 공통 코드라는 명칭으로 사용하던 것들을 좀더 구조화 시켜 Framework이라 부른다고 생각하면 될 것 같다.


이 Framework도 Component Framework, Application Framework, Web Framework 등 분류 기준에 따라 다양하게 분류가 된다.

여기서는 두가지로만 분류하겠다.

1. Component Framework (또는 Vendor Framework) : .NET Framework, J2EE Framework 과 같은 기능 중심의 Framework

2. Application Framework : Component Framework 기반으로 Application 내의 요소(Component)들간의 유기적인 연관 관계를 고려한 Framework (대표적인 것이 Apache Struts Framework, 다양한 SI회사에서 사용하는 Framework [필자의 회사에도 SummaFramework이라는 이름으로 가지고 있다] 등)


이러한 Framework을 활용하는 이유는 당연히 프로젝트의 생산성 향상 및 프로젝트의 표준화 지원을 통해 Quality 향상 등이 이유가 될 것이다. (사실 Framework이라는 표현을 쓰지 않을때에도 공통 코드 형태로 프로젝트 마다 사용해 왔던 것이다..)


이러한 Framework과 Architecture, Component, Library을 비교해 보면

Architecture는 시스템을 구성하고 있는 구성요소들 및 관계의 구조를 표현한 것으로 Framework 보다 좀더 추상적인 개념으로 보면 되겠다.

Component는 특정 기능을 수행하기 위해 잘 정의된 인터페이스를 통해 독립적으로 개발된 소프트웨어 단위로 Framework 기반에서 동작하는 모듈로 생각하면 되겠다.

Library는 재사용 가능한 함수와 루틴들을 모아 놓은 것으로 이러한 Library를 구조화 시켜 Framework을 만든다고 보면 되겠다.

재사용의 범위는 일반적으로

Library < Component < Framework < Architecture

라고 볼 수 있겠다.

 

C++ 프리프로세서 명령

16.1 서론

16.2 C++ 프리프로세서

16.3 파일의 include

16.4 단순한 문자열 치환

16.5 인수 없는 매크로

16.6 인수 있는 매크로

16.7 매크로 정의 해체

16.8 조건 컴파일러

16.9 #pragma

16.10 정리


 ◈ 16.2 C++프리프로세서

-C++프리프로세서 명령의 규칙은 C와 동일

-프리프로세서는 컴파일러에 넘겨주시 전에 프로그램의 소스 코드를 처리하는 프로그램이다.

-프리프로세서 명령은 기호 #이 앞에 놓여지고 프리프로세서 제어행이라고 부름.

-제어행의 내용에 따라 하나 또는 그 이상의 기능을 실행함.


■파일의 include

-다음이 있으면 파일이 include됨

 

 

 

 

#include

 

 

 


■문자열의 치환, 매크로 전개나 정의해제

-문자열의 치환, 매크로 전개나 정의해제 기능은, 다음의 명령으로 구현됨

 

 

 

 

#define 

#undef

 

 

 



■조건 컴파일의 명령

-조건 컴파일은, 다음의 제어행을 조합해서 구현됨

 

 

 

 

#if 

#else 

#endif 

#if 

#elif 

#endif 

#ifdef 

#endif 

#ifndef 

#endif

 

 

 


■디버그 작업의 보조

-다음의 제어행은 디버그를 지원함.

 

 

 

 

#pragma

 

 

 



 ◈ 16.3 파일의 include(1)


 

 

 

 

// test16_1.cpp//오류발생

//#include <iostream.h>

//#include <stdio.h>

void main(void)

{ 

  cout <<"Hi there ! \n";

        printf  ( "Hi there again ! \n");

}

 

 

 

-오류 매시지

 

 

 

 

error C2065: 'cout' : undeclared identifier

error C2297: '<<' : illegal, right operand has type 'char [13]'

error C2065: 'printf' : undeclared identifier

 

 

 


 ◈ 16.3 파일의 include(2)

 

 

 

 

// test16_2.cpp

#include <iostream.h>

#include <stdio.h>

void main(void)

{ 

  cout <<"Hi there ! \n";

        printf  ( "Hi there again ! \n");

}

 

 

 

-실행 결과

 

 

 

 

Hi there !

Hi there again !

 

 

 


-#include 명령은 컴파일 시에 명령 뒤에 있는 파일명의 모든 내용을 include함.

-헤더 파일 iostream.h는 cout의 정의를, stdio.h는 printf()의 정의를 포함


-#include 명령의 3가지 형식

■#include <filename>

 ∙<>괄호 안의 파일명은 컴파일러에게 현재의 작업 디렉토리 이외의 미리 준비된 디렉토리(표준 디렉토리)의 리스트로부터 그 파일을 찾도록 지시


■#include “filename”

∙컴파일러에게 현재의 작업 디렉토리 내에서 그 파일을 찾도록 지시


■#include “c:\wkspace\kdhong\"filename”

∙컴파일러에게 지정된 경로 내에서 그 파일을 찾도록 지시, 그 디렉토리에서 발견되지 않으면 표준 디렉토리를 찾음.

 

 

 

 

// test_16.3 cpp

#include <iostream.h>            // cout 에 필요

#include <stdio.h>              // printf()에 필요

#include "D:\Lecture2K-2\C++\nykwak.h"

void main(void)

{ 

        cout <<"Hi there ! \n";

        printf  ( "Hi there again ! \n");

        cout <<"a from nykwak.h is " <<a <<"\n";

}

 

 

 

-가령, D:\Lecture2K-2\C++\nykwak.h에 int a = 5;라는 선언문이 삽입되어 있을 경우, 실행 결과는, 다음과 같다.

 

 

 

 

Hi there !

Hi there again !

a from nykwak.h is 5

 

 

 


 ◈ 16.3 파일의 include(3)

 

 

 

 

// test_16.4 cpp//오류발생

#include <iostream.h>            // cout 에 필요

#include <stdio.h>              // printf()에 필요

#include "D:\Lecture2K-2\C++\kdhong.h"

void main(void)

{ 

        cout <<"Hi there ! \n";

        printf  ( "Hi there again ! \n");

        cout <<"a from kdhong.h is " <<a <<"\n";

}

 

 

 

-가령, D:\Lecture2K-2\C++\kdhong.h에

int a = 5

라는 선언문이 삽입되어 있을 경우, 메러 메시지는, 다음과 같다.

 

 

 

 

error C2144: syntax error : missing ';' before type 'void'

fatal error C1004: unexpected end of file found

 

 

 


 ◈ 16.4 단순한 문자열 치환

-일반적으로, #define 제어행을 사용할 때, 대문자를 사용.(그 이유는 프로그램 중에서 #define되는 변수를 쉽게 확인할 수 있기 때문.)

 

 

 

 

// test16_5.cpp//문자열 치환

#include <iostream.h>

#define HELLO "Hi there ! \n"

void main(void)

{ 

        cout <<HELLO ;

} 

 

 

 

-실행 결과

 

 

 

 

Hi there !

 

 

 


 ◈ 16.5 인수 없는 매크로

 

 

 

 

// test16_6.cpp//인수 없는 매크로

#include <iostream.h>         // I/O에 필요

#define SQUARE_TWO 2*2

void main(void)

{ 

        int a;

        a = SQUARE_TWO;

        cout <<"a is " <<a <<"\n";

}

 

 

 

-실행 결과

 

 

 

 

a is 4

 

 

 


-다음 제어행 중,

 

 

 

 

#define SQUARE_TWO 2*2

 

 

 

#define는 제어행으로, SQUARE_TWO는 매크로 템플리트이고, 2*2는 매크로 전개임.

 ◈ 16.6 인수 있는 매크로(1)

 

 

 

 

//test16_7.cpp 

#include <iostream.h>

#define ADD(X) (X+X)

void main(void)

{ 

        int b;

        b = ADD(4);

        cout <<"b is " <<b <<"\n";

}

 

 

 

-실행 결과

 

 

 

 

b is 8

 

 

 



 ◈ 16.6 인수 있는 매크로(2)

 

 

 

 

//test16_8.cpp//오류발생 

#include <iostream.h>

#define ADD (X) (X+X)

void main(void)

{ 

        int b;

        b = ADD(4);

        cout <<"b is " <<b <<"\n";

}

 

 

 

-오류 메시지

 

 

 

 

error C2065: 'X' : undeclared identifier

 

 

 



 ◈ 16.6 인수 있는 매크로(3)

 

 

 

 

//test16_9.cpp//오류발생 

#include <iostream.h>

//매크로명과 파라미터 사이의 괄호가 없는 것에 주의

#define ADD(X) X+X

void main(void)

{ 

        int b;

        b = ADD(4)*5;

        cout <<"b is " <<b <<"\n";

}

 

 

 

-실행 결과

 

 

 

 

b is 24

 

 

 


-test16_9.cpp의 동작 설명

 

 

 

 

 b = ADD(4)*5;

 

 

 

 

 

 

 

 b = 4 + 4 * 5;

 

 

 

와 같이 전개됨.

즉, 곱셈은 덧셈보다 연산우선순위가 빠르기 때문에 다음과 같이 계산됨

 

 

 

 

 b = 4 + (4 * 5);

 

 

 

그러나, 기대했던 것은 다음과 같은 것임.

 

 

 

 

 b = (4 + 4) * 5;

 

 

 

(따라서, 괄호를 생략해서는 안됨)


 ◈ 16.7 매크로 정의 해제

-이미 정의된 (#define) 매크로는 다음과 같은 제어행으로 정의를 해제할 수 있음.


 

 

 

 

#undef

 

 

 


 

 

 

 

// test16_10.cpp//오류발생

#include <iostream.h>

#define FOUR 4

void main(void)

{ 

        int a = FOUR;

        cout <<"a is " <<a <<"\n";

        #undef FOUR

      int b = FOUR;

        cout <<"b is " <<b <<"\n";

} 

 

 

 

-오류 메시지

 

 

 

 

error C2065: 'FOUR' : undeclared identifier

 

 

 


-메크로를 해제하는 이유는, 매크로 명을 필요로 하는 코드 부분만으로 유효 범위를 한정하기 위함.

 ◈ 16.8 조건 컴파일러

-조건 컴파일러는 소스 코드 중의 다음 키워드가 발견되면 수행됨.

 

 

 

 

#if - #else - #endif

#if - #elif  - #endif

#ifdef - #endif

#ifndef - #endif

 

 

 



16.8.1 #if - #else - #endif(1)

-키워드 #if에는 상수식, 코드블록이 이어지고, 그 뒤에 키워드 #endif가 놓여짐.

 

 

 

 

// test16_11a .cpp

#include <iostream.h>         // I/O 에 필요

#define FIVE 5

#define ZERO 0

void main(void)

{ 

       

              #if (FIVE)

                cout <<"FIVE is TRUE, i.e. non-zero \n";

        #else

                cout <<"FIVE is FALSE, i.e. zero \n";

        #endif

        #if (ZERO)

                cout <<"ZERO is TRUE, i.e. non-zero \n";

        #else

                cout <<"ZERO is FALSE, i.e. zero \n";

        #endif

        cout <<"This code is outside the blocks \n";

}

 

 

 

-실행 결과

 

 

 

 

FIVE is TRUE, i.e. non-zero

ZERO is FALSE, i.e. zero

This code is outside the blocks

 

 

 

16.8.1 #if - #else - #endif(2)

 

 

 

 

// test16_11.cpp//MS Visual C++의 경우, 실행되지만 오동작

#include <iostream.h>

void main(void)

{ 

        const int a = 5;

        const int b = 0;

        #if (a)

                cout <<"a is TRUE, i.e. non-zero \n";

        #else

                cout <<"a is FALSE, i.e. zero \n";

        #endif

        #if (b)

                cout <<"b is TRUE, i.e. non-zero \n";

        #else

                cout <<"b is FALSE, i.e. zero \n";

        #endif

       

        cout <<"This code is outside the blocks \n";

}

 

 

 

-실행 결과

 

 

 

 

a is FALSE, i.e. zero

b is FALSE, i.e. zero

This code is outside the blocks

 

 

 



16.8.1 #if - #else - #endif(3)

 

 

 

 

// test16_12.cpp//MS Visual C++의 경우, 실행되지만 오동작

#include <iostream.h>

void main(void)

{ 

        int a = 5;//a와 b는 변수로서 선언되고 있다.

        int b = 0;

        #if (a)

                cout <<"a is TRUE, i.e. non-zero \n";

        #else

                cout <<"a is FALSE, i.e. zero \n";

        #endif

        #if (b)

                cout <<"b is TRUE, i.e. non-zero \n";

        #else

                cout <<"b is FALSE, i.e. zero \n";

        #endif

       

        cout <<"This code is outside the blocks \n";

}

 

 

 

-실행 결과

 

 

 

 

a is FALSE, i.e. zero

b is FALSE, i.e. zero

This code is outside the blocks

 

 

 



16.8.1 #if - #else - #endif(4)


#if-#else-#endif와 정규 if-else-endif 제어 구조의 차이는, 전자에서는 case 평가를 프로그램이 컴파일되기 이전에 한다는 점이다. 테스트 조건 안에 변수를 두어서는 안된다. 왜냐하면, 변수의 값은 실행중에 변할 수도 있기 때문.

16.8.2 #if - #elif - #endif

#if-#elif-#endif는 #if-#else-#endif와 유사

 

 

 

 

// test16_11b.cpp

#include <iostream.h>         // I/O 에 필요

#define FIVE 5

#define ZERO 0

void main(void)

{ 

       

          #if (FIVE)

                cout <<"FIVE is TRUE, i.e. non-zero \n";

        #elif

                cout <<"FIVE is FALSE, i.e. zero \n";

        #endif

        #if (ZERO)

                cout <<"ZERO is TRUE, i.e. non-zero \n";

        #elif(ZERO)

                cout <<"ZERO is FALSE, i.e. zero \n";

        #endif

       

        cout <<"This code is outside the blocks \n";

}

 

 

 


-실행 결과

 

 

 

 

FIVE is TRUE, i.e. non-zero

This code is outside the blocks

 

 

 


16.8.3 #ifdef-#endif

-2개의 제어행 사이의 코드 블록은, 명령의 뒤에 있는 매크로명이 그 앞에 정의되어 있을 때에만 컴파일됨.

 

 

 

 

// test16_14.cpp

#include <iostream.h>

//#define COMPILE

void main(void)

{ 

        #ifdef COMPILE

                cout <<"This code will be compiled \n";

        #endif

} 

 

 

 


-실행 결과

 

 

 

 

 

 

 

 


16.8.4 #ifndef-#endif

-#indef-#endif문의 반대로, 제어행 사이 코드블록은, 매크로 명이 정의되어 있지 않을 때만 컴파일됨.

 

 

 

 

// test16_14.cpp

#include <iostream.h>

#define COMPILE

void main(void)

{ 

        #ifndef COMPILE

                cout <<"This code will be compiled \n";

        #endif

} 

 

 

 


-실행 결과

 

 

 

 

 

 

 

 


 ◈ 16.#pragma

-이 제어행은 컴파일러에 여러 가지 지령을 줄 수 있다. 특수한 지령은 처리계의 독자적인 지령이다.


MSDNdpt의 progma에 대한 설명

Each implementation of C and C++ supports some features unique to its host machine or operating system. Some programs, for instance, need to exercise precise control over the memory areas where data is placed or to control the way certain functions receive parameters. The #pragma directives offer a way for each compiler to offer machine- and operating-system-specific features while retaining overall compatibility with the C and C++ languages. Pragmas are machine- or operating-system-specific by definition, and are usually different for every compiler.


Syntax


#pragma token-string


The token-string is a series of characters that gives a specific compiler instruction and arguments, if any. The number sign (#) must be the first non-white-space character on the line containing the pragma; white-space characters can separate the number sign and the word pragma. Following #pragma, write any text that the translator can parse as preprocessing tokens. The argument to #pragma is subject to macro expansion.


If the compiler finds a pragma it does not recognize, it issues a warning, but compilation continues.


Pragmas can be used in conditional statements, to provide new preprocessor functionality, or to provide implementation-defined information to the compiler. The C and C++ compilers recognize the following pragmas:


alloc_text comment init_seg1 optimize

auto_inline component inline_depth pack

bss_seg data_seg inline_recursion pointers_to_members1

check_stack function intrinsic setlocale

code_seg hdrstop message vtordisp1

const_seg include_alias once warning

+ Recent posts