헤더파일

템플릿 본문

C++

템플릿

헤더파일 2018. 3. 8. 12:19

빌드하면 비주얼 스튜디오 속에 c++ 컴파일러가 파일을 읽기 시작한다.

#include "iostream";

include는 헤더안에 파일을 모두 복사한다. 


template<typename T>

void exchange(T a)

{

T b = a;

}

쭉 가다가 템플릿 코드를 만나면 호출된 함수의 자료형으로 함수 코드를 찍어낸다.


정수형으로 불렀다면

template<>

void exchange(int a)

{

int b = a;

}

이런식으로


템플릿은 인간이 쓴 코드와 똑같아서 효율이 떨어지는 부분이 전혀 없다.

컴파일러는 자료형을 유추할 수 있어서 자료형 명시를 생략해도 된다. 사용자 정의 클래스일 경우는 명시해야 한다.


class Dog

{

public:

Dog() {}

Dog(const char* name, int age)// const는 전달된 인자를 읽기만 하겠다.

{

m_name = name;

m_age = age;

}

Dog* operator=(Dog& param)

{

m_name = param.m_name;

m_age = param.m_age;

return this;

}

const char* getName() const{ return m_name; }//함수의 리턴값은 레퍼런스를 붙이는 건 좋지않다.

int getAge()const { return m_age; }


friend ostream& operator<<(ostream&, const Dog&);


private:

const char* m_name;

int m_age;

};



int main()

{

Dog dogs[5]


{

{ "멍멍이",1 },{ "야옹이",3 },{ "멍뭉이",6 },{ "티라노",2 },{ "티티",4 }

};


//Save();

}


Dog를 나이 오름차순으로 정렬.

.dogs[5]는 연속된 메모리에 5마리가 들어있다.

메모리에는 강아지의 이름이 들어가 있을까? 

이름은 char*형이고 동적할당 했으므로 강아지 공간에는 없다




qsort 예제


먼저 c함수 중 범용함수인 qsort를 사용해보자. c함수중 generic(범용)함수로 자료형에 아무 상관 없는 함수(qsort는 배열일때만 정렬하는 전용함수 이긴 하다.)


qsort는 이렇게 구성되어 있다. qsort(배열, 몇개, 한개크기, 어떻게)

프로그램에서 방법을 전달할 수 있는 방법은 함수 포인터가 있다.



STL은 자료구조와 알고리즘이 연결되어있다. 그래서 자료구조가 중요하다.

자료구조의 핵심은 메모리 구조. 배열은 컴파일 시간에 크기가 정해지고 물리적으로 연속된 자료구조.


함수의 이름은 항상 함수의 시작번지이기 떄문에 값을 바꾸려면 항상 역참조 해야 한다.

함수의 호출은 (*function)(); 이렇게 써야 정식으로 호출한다.


int compare(const void* a, const void* b)

{

int num1 = *(int *)a;    // void 포인터를 int 포인터로 변환한 뒤 역참조하여 값을 가져옴

int num2 = *(int *)b;    // void 포인터를 int 포인터로 변환한 뒤 역참조하여 값을 가져옴


if (num1 < num2)    // a가 b보다 작을 때는

return -1;      // -1 반환


if (num1 > num2)    // a가 b보다 클 때는

return 1;       // 1 반환


return 0;    // a와 b가 같을 때는 0 반환

}


단순화하면


int compare(const void* a, const void* b)

{

return *(int*)a - *(int*)b;

}



qsort틑 어떤 자료형이 올 지 모르니 넘기는 함수는 const void* 형으로 만든다.

하지만 프로그래머는 비교대상의 자료형이 먼지 알고있으므로 내가 쓰고 있는 자료형으로 캐스팅 해준다.



int main()

{

int a[10]{1,3,5,7,9,2,4,6,8,10};

qsort(a, _countof(a), sizeof(int),compare );


for (int i = 0; i < 10; ++i)

cout << a[i] << endl;

//Save();

}



위에가 c언어식 표현이라면 c++에서는 람다를 사용한다.


int main()

{

int a[10]{1,3,5,7,9,2,4,6,8,10};

qsort(a, _countof(a), sizeof(int), [](const void* a, const void* b) {return *(int*)a - *(int*)b; });


for (int i = 0; i < 10; ++i)

cout << a[i] << endl;

//Save();

}



실제 정렬할 때는 정수가 아닌 객체를 정렬한다.


class Dog

{

public:

string name;

int age;


Dog(string name, int age):name(name),age(age) {}

friend ostream& operator<<(ostream& os, const Dog& dog);

};


ostream& operator<<(ostream& os,const Dog& dog)

{

os << dog.age << " " << dog.name;


return os;

}


int main()

{

Dog a[5]{ {"멍멍이",7},{"야옹이",9},{"티라노",1},{"뭉뭉이",3},{"몽실이",12} };


qsort(a, _countof(a), sizeof(Dog), [](const void* a, const void* b) 

{return ((Dog*)a)->age - ((Dog*)b)->age; });


for (int i = 0; i < _countof(a); ++i)

cout <<a[i] << endl;

Save();

}


->연산자가  *연산자보다 우선이므로 꼭 괄호해야 한다.

friend 함수는 private 멤버에도 접근할 수 있다.


참고 . get함수는 함수안에서 값이 변경될리 없으므로 const를 꼭 붙인다.


(Dog*)는 무식한 c스타일의 캐스팅.

c++은 자료형하나하나가 소중해서 아무거로나 바꾸는건 자료형 점검체계가 무력해지는 일.

static_cast<Dog*>(a) 로 캐스팅하면 오류가 나는데 const가 유지되지 않았기 때문이다.

이런식으로 c++식 캐스팅은 자료형 점검체계가 있다.


static_cast<const Dog*>(a) 로 해야 한다.



최종 c++식 코드


class Dog

{

private:

string name;

public:

int age;


Dog(string name, int age):name(name),age(age) {}

friend ostream& operator<<(ostream& os, const Dog& dog);


int getAge()const { return age; }

};


ostream& operator<<(ostream& os,const Dog& dog)

{

os << dog.age << " " << dog.name;


return os;

}


int main()

{

Dog a[5]{ {"멍멍이",7},{"야옹이",9},{"티라노",1},{"뭉뭉이",3},{"몽실이",12} };


qsort(a, _countof(a), sizeof(Dog), [](const void* a, const void* b) {return static_cast<const Dog*>(a)->getAge() - static_cast<const Dog*>(b)->getAge(); });





for (int i = 0; i < _countof(a); ++i)

cout <<a[i] << endl;

Save();

}



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

스마트 포인터  (0) 2018.04.05
이동  (2) 2018.03.29
템플릿 - 3  (0) 2018.03.22
템플릿- 2  (0) 2018.03.19
다형성, 레퍼런스  (0) 2018.03.05
Comments