Presentation is loading. Please wait.

Presentation is loading. Please wait.

C++ 프로그래밍 25 2008년 2학기 전자정보공학대학 컴퓨터공학부.

Similar presentations


Presentation on theme: "C++ 프로그래밍 25 2008년 2학기 전자정보공학대학 컴퓨터공학부."— Presentation transcript:

1 C++ 프로그래밍 25 2008년 2학기 전자정보공학대학 컴퓨터공학부

2 Outline Review: 템플릿과 STL

3 템플릿과 STL

4 템플릿의 활용방법 템플릿 클래스 템플릿 함수

5 템플릿 클래스의 사용 템플릿 매개 변수의 사용 [29-1]

6 템플릿 함수의 사용 template<typename T> T max(T a, T b) {
if(a>b) return a; else return b; }

7 템플릿 함수의 사용 모든 타입을 위한 max() 함수 - 사용 int main() { int i1 = 5, i2 = 3;
int i3 = max(i1, i2); double d1 = 0.9, d2 = 1.0; double d3 = max(d1, d2); return 0; }

8 템플릿 사용 시 유의할 점 템플릿은 컴파일 시간에 코드를 만들어낸다. 템플릿 함수의 정의(구현)는 헤더 파일에!
템플릿의 사용으로 인한 속도 저하는 없다 컴파일 시간이 오래 걸림 (하지만 크게 문제가 될 정도는 아님) 템플릿 함수의 정의(구현)는 헤더 파일에! 컴파일 시간에 클래스나 함수를 만들어내기 위해서는 헤더 파일에 위치할 필요가 있다. (컴파일 시간에는 다른 구현 파일의 내용을 확인할 수 없다. )

9 Standard Template Library
C++ = 언어 클래스, 멤버함수, 상속, 템플릿, 오버로딩 등의 기술 STL = 템플릿 기반의 편한 사용 툴: 클래스, 함수 등의 집합체 array 나 pointer를 대체하는 데이터 관리에 용이

10 Standard Template Library
구성: Container 같은 타입의 원소를 관리하는 데이터 구조 지원 클레스 list, vector, deque, … Algorithm Container에 대해 복사, 전환, 병합, 정렬 random_shuffle, replace, fill, remove, sort, … Iterator 원소의 관리 방법 ( = 포인터) 함수 개체 함수 연산자 ( ) 를 오버로딩

11 STL 컨테이너 자주 사용하는 STL의 컨테이너 클래스 [표 29-1]

12 STL 컨테이너: vector 데이터의 보관: std::vector 클래스
동적 메모리 할당을 위한 컨테이너: array를 대체

13 STL 컨테이너: vector 준비작업: #include <vector> using namespace std;
사용법(정의): 예시: #include <vector> using namespace std; vector <변수형> 변수이름; vector <int> vInts ;

14 STL 컨테이너: vector 사용법 : 크기 설정 및 값 할당 예외처리 안 함 예외처리 함(throw)
operator [ ] 를 사용 .at ( int index ) 함수를 사용 예외처리 안 함 예외처리 함(throw) vector <int> vInts (100); vInts[0] = 10; vInts[1] = 20; vInts.at(2) = 30;

15 STL 컨테이너: vector 여러 생성자 vector <Widget> vWidgets;
vector <Widget> vWidgets(500, Widget(0)); vector <Widget> vWidgetsCopying(vWidgets);

16 STL 컨테이너: vector vector에 동적 원소 추가 예제: vector <int> vInts;
.push_back (element) 함수 사용 vector <int> vInts; for(int i=0; i<10; i++) vInts.push_back(i);

17 STL 컨테이너: vector 다른 함수들 assign
Erases a vector and copies the specified elements to the empty vector. at Returns a reference to the element at a specified location in the vector. back Returns a reference to the last element of the vector. begin Returns a random-access iterator to the first element in the container. capacity Returns the number of elements that the vector could contain without allocating more storage. clear Erases the elements of the vector. empty Tests if the vector container is empty. end Returns a random-access iterator that points just beyond the end of the vector. erase Removes an element or a range of elements in a vector from specified positions. front Returns a reference to the first element in a vector. get_allocator Returns an object to the allocator class used by a vector. insert Inserts an element or a number of elements into the vector at a specified position. max_size Returns the maximum length of the vector. pop_back Deletes the element at the end of the vector. push_back Adds an element to the end of the vector. rbegin Returns an iterator to the first element in a reversed vector. rend Returns an iterator to the end of a reversed vector. resize Specifies a new size for a vector. reserve Reserves a minimum length of storage for a vector object. size Returns the number of elements in the vector. swap Exchanges the elements of two vectors. vector Constructs a vector of a specific size or with elements of a specific value or with a specific allocator or as a copy of some other vector.

18 STL 컨테이너: list 데이터의 보관: list 클래스 – linked list #include <list>
#include <iostream> int main() { // int 타입을 담을 링크드 리스트 생성 list<int> intList; // 1 ~ 10까지 링크드 리스트에 넣는다. for (int i = 0; i < 10; ++i) intList.push_back(i);

19 STL 컨테이너: list 데이터의 보관: list 클래스 – 삭제 및 데이터 추출 // 위에서 계속
// 5를 찾아서 제거한다. intList.remove(5); // 링크드 리스트의 내용을 출력한다. list<int>::iterator it; for (it=intList.begin(); it != intList.end(); it++) std::cout << *it << "\n";

20 STL 컨테이너: list list 클래스의 탐색 [29-2]

21 STL 알고리즘(1) 자주 사용하는 STL의 알고리즘 함수 [표 29-2]

22 STL 알고리즘(2) sort() 함수를 사용하는 예(vector나 deque만 가능) (list는 불가)
#include <algorithm> #include <vector> #include <iostream> using namespace std; int main() { // 동적 배열을 생성해서 임의의 영문자를 추가한다. vector<char> vec; vec.push_back( 'e'); vec.push_back( 'b'); vec.push_back( 'a'); vec.push_back( 'd'); vec.push_back( 'c');

23 STL 알고리즘(2) sort() 함수를 사용하는 예 // sort() 함수를 사용해서 정렬한다.
sort( vec.begin(), vec.end() ); // 정렬 후 상태를 출력한다. cout << "vector 정렬 후\n"; vector<char>::iterator it; for (it = vec.begin(); it != vec.end(); ++it) std::cout << *it; return 0; }

24 참고 사이트

25 예외 처리(Exception Handling)
예외란? 우리가 당연하다고 가정한 상황이 거짓이 되는 경우 대표적인 예외 컴퓨터에 사용 가능한 메모리가 부족한 경우 당연히 있을 것이라 생각한 파일이 없는 경우 사용자가 잘못된 값을 입력하는 경우 예외 처리란? 프로그램이 항상 올바르게 동작할 수 있도록 처리하는 것 예) 동적 메모리 할당이 실패한 경우 예외 처리를 잘 하지 못한 프로그램  비정상 종료 예외 처리를 잘 한 프로그램  사용자가 작업 중이던 정보를 잘 보관한 후 정상 종료

26 DynamicArray 클래스 만들기 동적 배열 클래스 class DynamicArray { public:
동적 배열 클래스 class DynamicArray { public: // 생성자, 소멸자 DynamicArray(int arraySize); ~DynamicArray(); // 접근자 void SetAt(int index, int value); int GetAt(int index) const; int GetSize() const; protected: int* arr; // 할당한 메모리 보관 int size; // 배열의 길이 보관 };

27 DynamicArray 클래스 DynamicArray::DynamicArray(int arraySize) {
arr = new int [arraySize]; size = arraySize; } DynamicArray::~DynamicArray() delete[] arr;

28 DynamicArray 클래스 // 원소의 값을 바꾼다
void DynamicArray::SetAt(int index, int value) { arr[index] = value; } // 원소의 값을 반환한다 int DynamicArray::GetAt(int index) const return arr[index]; // 배열의 길이를 반환한다. int DynamicArray::GetSize() const return size;

29 DynamicArray 클래스의 문제점 SetAt() 함수나 GetAt() 함수에 너무 큰 인덱스를 넘겨주면?  할당되지 않은 메모리를 건드림 [24-2]

30 반환 값을 사용한 예외 처리(1) 함수의 실행 전 조건을 검사 조건이 만족 못하면 false를 리턴

31 반환 값을 사용한 예외 처리(2) SetAt() 함수가 실패했을 때 반환 값으로 알려주는 예 // 원소의 값을 바꾼다
// 인덱스의 범위가 잘못된 경우 false 반환 bool DynamicArray::SetAt(int index, int value) { // 인덱스를 확인한다. if (index < 0 || index >= GetSize() ) return false; arr[index] = value; return true; }

32 반환 값을 사용한 예외 처리(3) 실제 사용시: // 크기가 10인 배열 객체를 만든다.
DynamicArray arr(10); // 올바른 인덱스를 참조한다 bool b; b = arr.SetAt(5, 0); if (!b) cout << "arr[5] 사용 실패!!\n"; // 일부러 범위 밖의 인덱스를 참조한다 b = arr.SetAt(20, 0); cout << "arr[20] 사용 실패!!\n";

33 반환 값을 사용한 예외 처리(4) 반환 값을 사용한 예외 처리의 문제점
본연의 소스 코드와 예외 처리 코드가 뒤엉켜서 지저분하고 읽기 어렵다. 예외 처리 때문에 반환 값을 본래의 용도로 사용할 수 없다.

34 구조적 예외 처리(1) try와 throw, catch를 사용 try { if(예외발생) throw; 수행할 일(); }
오류 발생 시 할 일;

35 구조적 예외 처리(2) throw, try, catch의 사용 [24-5]

36 구조적 예외 처리(3) C++의 구조적 예외 처리를 사용해서 실패를 알리는 예 // 원소의 값을 바꾼다
void DynamicArray::SetAt(int index, int value) { // 인덱스의 범위가 맞지 않으면 예외를 던진다 if (index < 0 || index >= GetSize()) throw "Out of Range!!!"; arr[index] = value; }

37 구조적 예외 처리(4) C++의 구조적 예외 처리를 사용해서 실패를 알리는 예 // 크기가 10인 배열 객체를 만든다.
DynamicArray arr(10); try { arr.SetAt(5, 100); arr.SetAt(8, 100); arr.SetAt(10, 100); } catch(const char* ex) cout << "예외 종류 : " << ex << "\n";

38 구조적 예외 처리(5) 예외의 발생과 실행의 흐름 [24-6]

39 예외 객체의 사용(1) 객체를 예외로 던지면 다양한 정보를 함께 전달할 수 있다. class MyException {
public: const void* sender; // 예외를 던진 객체 주소 const char* description; // 예외에 대한 설명 int info; // 부가 정보 MyException(const void* sender, const char* description, int info) this->sender = sender; this->description = description; this->info = info; } };

40 예외 객체의 사용(2) 객체를 예외로 던지면 다양한 정보를 함께 전달할 수 있다. // 원소의 값을 바꾼다
void DynamicArray::SetAt(int index, int value) { // 인덱스의 범위가 맞지 않으면 예외를 던진다 if (index < 0 || index >= GetSize()) throw MyException( this, "Out of Range!!!", index); arr[index] = value; }

41 예외 객체의 사용(2) 다형성을 사용해서 일관된 관리를 할 수 있다. // 인덱스와 관련된 예외
class OutOfRangeException : public MyException { ... }; // 메모리와 관련된 예외 class MemoryException : public MyException

42 예외 객체의 사용(2) 다형성을 사용해서 일관된 관리를 할 수 있다. try {
// OutOfRangeException& 혹은 // MemoryException& 타입의 // 예외 객체를 던진다고 가정 } catch(MyException& ex) // OutOfRangeException 과 // MemoryException 모두 // 여기서 잡을 수 있다. cout << "예외에 대한 설명= " << ex.description << "\n";

43 구조적 예외 처리의 규칙(1) 예외는 함수를 여러 개 건너서도 전달할 수 있다 void A() int main() { {
B(); } void B() C(); void C() throw 337; int main() { try A(); } catch(int ex) cout << "예외 = " << ex; return 0;

44 구조적 예외 처리의 규칙(2) 받은 예외를 다시 던질 수 있다. int main() { try { A();}
catch(char c){ cout << "main() 함수에서 잡은 예외 = " << c << "\n"; } return 0; void A() try { B(); } catch(char c) { cout << "A() 함수에서 잡은 예외 = " << c << "\n"; throw; void B() throw 'X';

45 구조적 예외 처리의 규칙(3) try 블럭 하나에 여러 개의 catch 블럭 int main() { try{ A(); }
catch(MemoryException& ex) cout << "MemoryException 타입으로 잡혔음\n"; } catch(OutOfRangeException& ex) cout << "OutOfRangeException 타입으로 잡혔음\n"; catch(...) cout << "그 밖의 타입\n"; return 0;

46 구조적 예외 처리의 규칙(4) Catch 블록이 여럿인 경우 [24-11]

47 구조적 예외 처리의 규칙(5) 예외 객체는 레퍼런스로 받는 것이 좋다. try {
MyException e( this, “객체”, 0 ); throw e; } catch( MyException& ex) cout << ex.description << “\n”;

48 리소스의 정리(1) 리소스를 정리하기 전에 예외가 발생한 경우의 문제점 확인 try { // 메모리를 할당한다.
char* p = new char [100]; // 여기까지 실행되었음을 출력한다. cout << "예외가 발생하기 전\n"; // 예외를 던진다. throw "Exception!!"; // 이곳은 실행되지 않음을 출력한다. cout << "예외가 발생한 후\n"; // 메모리를 해제한다. (실행 안됨) delete[] p; p = NULL; } catch(const char* ex) cout << "예외 잡음 : " << ex << "\n";

49 리소스의 정리(2) 실행의 흐름 [24-13]

50 소멸자를 사용한 리소스 정리(1) 예외가 발생한 경우라도 객체의 소멸자는 반드시 호출된다  소멸자를 사용 메모리 정리
// 스마트 포인터 클래스 class SmartPointer { public: SmartPointer(char* p) : ptr(p) } ~SmartPointer() // 소멸자가 호출되는 것을 확인한다 cout << "메모리가 해제된다!!\n"; delete[] ptr; char * const ptr; };

51 소멸자를 사용한 리소스 정리(2) try { // 메모리를 할당한다. char* p = new char [100];
// 할당된 메모리의 주소를 스마트 포인터에 보관한다. SmartPointer sp(p) cout << "예외가 발생하기 전\n"; throw "Exception!!"; // 이곳은 실행되지 않음을 출력한다. cout << "예외가 발생한 후\n"; // 메모리를 해제해줄 필요가 없다. // delete[] p; // p = NULL; } catch(const char* ex) cout << "예외 잡음 : " << ex << "\n";

52 생성자에서의 예외 처리 생성자에서 예외가 발생한 경우에는 객체가 생성되지 않은 것으로 간주되므로 소멸자가 호출되지 않는다.
그러므로, 생성자에서 예외가 발생한 경우에는 반드시 생성자 안쪽에서 리소스를 정리해야 한다.

53 생성자에서의 예외 처리 DynamicArray::DynamicArray(int arraySize) { try
// 동적으로 메모리를 할당한다. arr = new int [arraySize]; // 배열의 길이 보관 size = arraySize; // 여기서 고의로 예외를 발생시킨다. throw MemoryException( this, 0); } catch(...) cout << "여기는 실행된다!!\n"; delete[] arr; // 리소스를 정리한다. throw; // 예외는 그대로 던진다.

54 소멸자에서의 예외 처리 소멸자에서 예외가 발생하는 경우에는 프로그램이 비정상 종료할 수 있으므로, 소멸자 밖으로 예외가 던져지지 않게 막아야 한다. DynamicArray::~DynamicArray() { try // 메모리를 해제한다. delete[] arr; arr = 0; } catch(...)

55 auto_ptr C++에서 기본적으로 제공하는 스마트 포인터 #include <memory>
using namespace std; int main() { // 스마트 포인터 생성 auto_ptr<int> p( new int ); // 스마트 포인터의 사용 *p = 100; // 메모리를 따로 해제해 줄 필요가 없다 return 0; } [24-17]

56 bad_alloc 동적 메모리 할당 실패시 던져지는 예외 클래스 #include <new>
#include <iostream> using namespace std; int main() { try // 많은 양의 메모리를 할당한다. char* p = new char [0xfffffff0]; } catch(bad_alloc& ex) cout << ex.what() << "\n"; return 0;


Download ppt "C++ 프로그래밍 25 2008년 2학기 전자정보공학대학 컴퓨터공학부."

Similar presentations


Ads by Google