반응형

template

  • 템플릿 매개 변수에 대해 제공하는 인수를 기반으로 컴파일 시간에 일반 형식 또는 함수를 생성하는 구문

  • 함수 또는 클래스에 사용되는 자료형이, 특정 자료형에 의존하지 않게 할때 쓰임 ( Generic Programming )

  • 여러가지 자료형에 대해서 비슷한 코드를 반복해서 작성하는 것을 방지해줌

 

 

함수 템플릿

"template <typename T>" 또는 "template<class T>" 함수위에 한줄 작성, 여기서 T 자료형으로 매크로(#define)처럼 치환될 타입이름, 아직 정해지지 않은 타입이름이다, 많이 쓰이는 이름으로 T 쓰인다, T 쓰지 않고, T1, T2 등으로 써도 컴파일된다. 

T 매개변수의 타입으로도 쓰일수 있고, 함수 스코프 안에서 자유롭게 T 사용할 있다

T 함수 호출할때 , 함수이름<자료형>(); 이런식으로 미리 정해서 호출할 수도 있고

정하지 않고도 81번라인~ 85번라인의 코드처럼 함수를 호출 해도 템플릿 코드가 동작한다.

74 라인의 경우, OutputType<int>(); T int 치환된것이다

int, float 말고도 사용자 정의 자료형(class) 들어갈 있다.

 

주의

사용자 정의 자료형을 함수 템플릿의 T 쓸때 주의할 점은 함수 안에서 비교, 산술 등등의 연산자를 사용하는 경우 사용자 정의한 클래스에 연산자 오버로딩이 되있어야 한다.

그렇지 않을 경우 error C2676 발생 한다

error C2676 이란? https://docs.microsoft.com/ko-kr/cpp/error-messages/compiler-errors-2/compiler-error-c2676?view=vs-2019

 

IsSame 실행 있게 MyClass == 연산자 오버로딩을 해주고, int 멤버 변수를 만든뒤, 생성자로 기본값을 설정해야 선언 있게 만들었다

정상 작동하는걸 있다, template 함수에 내가 만든 클래스형을 인자로 호출 할때는 함수 안에서 연산자를 쓰는지 여부를 파악해야 하며, 연산자를 쓴다면 연산자 오버로딩이 필요하다.

 

 

 

또한 위처럼 typename 여러 있다.

 

 

클래스 템플릿

클래스를 디자인할때 템플릿을 사용할 있다,

클래스 선언시에 클래스옆에<자료형> 붙여서

어떤 자료형이 오게 될지를 먼저 정해줘야 한다.(Template은 컴파일 시간에 동작하기 때문에)

 

또한 템플릿 클래스의 메소드(멤버 함수)들은 T 자유롭게 사용할 있다.

tem2 T float 정해졌기 때문에 tem2 메소드 Output2 인자로 float 요구하는 있다.

 

 

주의

template 클래스에서는 위와 같이 헤더파일과 .cpp 파일 분리를 해도, 원활한 분리가 되지 않는다.

빌드를 하면 아래와 같은 링크 에러가 발생한다.

error LNK2019 가   발생했다 .

 

 

원인

헤더 파일을 .cpp 파일에 include 하게 되면 헤더파일의 내용을 cpp 파일의 맨앞부터 복사 해서 붙여놓은 것과 같다, 컴파일은 .cpp파일에서 하게 되어있다. 필요한 함수 또는 변수 선언이 있다면 헤더파일에서 찾는것이다.

그래서 Template_2_main.cpp 파일의 경우 6번라인에 있는 클래스 CTemplate "CTemplate.h" 파일에서 찾은뒤 T int 치환해서 instance 생성한다

문제는 Output 함수의 body 컴파일 할때는 CTemplate.cpp에서 컴파일을 하는데

CTemplate.h include CTemplate.cpp 파일의 경우 main 함수에서 int T 정했다는 수가 없다. CTemplate.cpp T 쓰는함수들은 여전히 동일하게 T인것이다.

그래서 Output 함수를 컴파일 할때 T int 치환을 안하게 된다

 

해결책

explicit instantiation

CTemplate.cpp 파일에 위와 같이 explicit instantiation(명시적 인스턴스화) 해주면 된다.

 

explicit instantiation 하는법

 

template 클래스이름<특정자료형>::함수이름(특정자료형 매개변수이름) ;

 

반응형

'C++' 카테고리의 다른 글

string vs stringstream  (0) 2020.09.04
template singleton  (0) 2020.07.21
c++ typeid 연산자  (0) 2020.03.16
References(L-value reference, R-value reference)  (0) 2020.03.13
C++ lvalue, rvalue, xvalue, glvalue, prvalue  (0) 2020.03.12
반응형

c++ typeid 연산자

출처 https://docs.microsoft.com/ko-kr/cpp/cpp/typeid-operator?view=vs-2019

typeid(type-id)

typeid(expression)

 

  • typeid 연산자를 사용 하면 런타임에 개체의 형식을 확인할 있음
  • typeid 결과값은 const type_info& 이다, 

출처 https://docs.microsoft.com/ko-kr/cpp/cpp/type-info-class?view=vs-2019

class type_info {

public:

    type_info(const type_info& rhs) = delete; // cannot be copied

    virtual ~type_info();

   

//--연산자 오버로딩

    _CRTIMP_PURE bool operator==(const type_info& rhs) const;

    type_info&            operator=(const type_info& rhs) = delete; // cannot be copied

    _CRTIMP_PURE bool operator!=(const type_info& rhs) const;

//연산자 오버로딩--

 

 

_CRTIMP_PURE int before(const type_info& rhs) const;

 

    size_t hash_code() const;

    size_t hash_code() const noexcept;

    _CRTIMP_PURE const char* name() const;

    _CRTIMP_PURE const char* raw_name() const;

};

 

 

 

typeid(자료형 또는 변수이름 또는 함수이름 또는 인스턴스 등등).name() 실행하면

자료형의 이름을 리턴한다

 

 

또한 리턴하는 자료형의 이름은 const char* 라는 것을 있다

혹시나 해서 const의 위치까지 구분해서 리턴하는지 테스트 해봤는데

const 의 위치까지 따로 구분해서 리턴하지는 않는다

참고로 포인터 변수는 const의 위치에 따라서 아래와 같이 수정 가능한 부분이 다르다

 const 자료형*  : 역참조 값을 수정 X , 가리키는 주소는 수정 O

 자료형* const  : 역참조 값을 수정 O, 가리키는 주소 수정 X

 const 자료형* const : 역참조값 수정 X, 가리키는 주소 수정 X

 

그러나 typeid(자료형).name() 으로 위 사항들까지는 구별 할 수 없다.

그저 자료형 앞에 const 가 있으면 출력할때

"자료형 const" 으로 출력하고

포인터 변수인 경우 "자료형 * const" 로 출력한다

 

 

거의   모든   자료형의   이름을  const char * 로  리턴받을 수   있다 .

 

반응형
반응형

메모리 초기화 함수

memset( void * _Dst,

            int _Val,

            size_t _Size );

연속된 메모리 초기화 함수, _Dst 시작되는 메모리 주소를 넣어주고, _Size sizeof(자료형*) * 개수 만큼 _Val 값으로 모두 초기화 해준다, for 대신에 사용할 있다.

 

 

 

메모리 복사 함수

memcpy( void* destination,

            void* source,

            size_t num );

 

memmove( void* destination,

               void* source,

               size_t num );

함수 모두 메모리의 일부분을 복사하여 가리키는 위치에 붙여넣는다, source 가리키는 곳부터 num 바이트 만큼을 destination 가리키는 곳에 복사한다. 또한 source '\0' 종료 문자(null terminating character) 검사하지 않는다. 언제나 정확히 num 바이트 만큼을 복사한다.

 

두함수의 차이는

memcpy 메모리의 내용을 직접 copy 하고, memmove copy 메모리의 내용을 임시 버퍼에 저장한 copy 한다, 그렇기 때문에 memcpy memory overlap 현상이 일어날 있고, memmove 그렇지 않지만

memcpy 비해 속도가 떨어진다

속도는 memcpy 좋고, 안정성은 memmove 좋다 하지만 2019 기준으로 memmove 속도가 memcopy 많이 따라잡아서 memmove 사용을 권장하는편이다

 

오버 플로우 문제를 방지하기 위해 destination source 가리키는 배열의 크기는 반드시 num 바이트 이상이어야 하며, 서로 겹치면 안된다.(만일 메모리 블록이 겹쳐져 있다면  memmove 함수를 이용하는것이 좋다)

반응형

'C' 카테고리의 다른 글

expression(표현식)  (0) 2020.03.12
Local Variable, Global Variable, Static Variable  (0) 2020.02.28
fseek, ftell, 파일 크기 알아내기  (0) 2020.02.25
FileStream Input Output  (0) 2020.02.22

+ Recent posts