티스토리 뷰
*다향성(Pholymophism)
는 객체간의 결합(coupling)을 약하게 만들어서, 객체 간의 연결을 유연하게 해줍니다.(Virtual Function 이용)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <iostream> using namespace std; class Parent { public : int val = 1; 가상함수 virtual void function() { cout << val << endl; } }; class Child_2 :public Parent { public : void function() { cout << val * 2 << endl; } }; class Child_3 :public Parent { public: void function() { cout << val * 3 << endl; } }; int main() { Parent *p[3] = { NULL }; p[0] = new Parent; p[1] = new Child_2; p[2] = new Child_3; for (int i = 0; i < 3; i++) { p[i]->function(); } } | cs |
virtual void function()에서 virtual 키워드를 제거하였을 때 모두 1이 출력됩니다.(=Parent의 function()이 출력)
*순수가상함수
1 2 3 4 5 | class Parent { public : int val = 1; 순수가상함수 virtual void function() = 0; }; | cs |
virtual void function() = 0;와 같이 순수가상함수를 포함하는 class를 추상class라고 지칭하며,
추상class는 객체 생성이 불가능 합니다.
(Abstract class <-> Concrete Class)
순수가상함수의 경우, 함수의 내용을 구현하지않아도 컴파일오류가 뜨지 않습니다.
*오버로딩과 오버라이딩
정상적인 실행
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Parent { public : int val = 1; void function() { cout << val<<endl; } void function(int n) { val = n; cout << val<<endl; } }; class Child :public Parent { public : //void function(); }; int main() { Child c; c.function(); c.function(5); } | cs |
부모클래스에서 오버로딩된 함수 중 하나라도 오버라이딩 한다면, 나머지 함수는 사용할 수 없습니다.
1 2 3 4 | class Child :public Parent { public : void function(); }; | cs |
Child에서 function()을 오버라이딩했으므로 Parent의 function()과 오버로딩된 function(int n)은 사용할 수 없습니다.
*예외 객체의 사용
다양한 정보를 함께 throw할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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; } }; class DynamicArray { protected: int size; int *arr; public : DynamicArray(int size) { this->size = size; arr = new int[this->size]; } ~DynamicArray() { delete[] arr; } void SetAt(int index, int value) { if (index < 0 || GetSize() <= index) { throw MyException(this, "Out of Range", index); } arr[index] = value; } int GetAt(int index) const { return arr[index]; } int GetSize() const { return size; } }; int main() { DynamicArray da(5); try { da.SetAt(5, 6); } catch(MyException &e){ cout <<"error message : "<< e.description<<endl<< "information : "<<e.info<<endl; } } | cs |
추가로, 다형성을 사용하여 예외에대한 관리를 할 수 있습니다.
1 2 3 | class OutOfRangeException : public MyException class MemoryException : public MyException | cs |
*예외처리 규칙
함수를 건너서 throw할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | void B() { throw "Exception"; } void A() { B(); } int main() { try { A(); } catch (char *ex) { cout << ex << endl; } } | cs |
A에서 B의 throw를 받아 catch, 다시 throw하여 main에서 catch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | void B() { throw "Exception"; } void A() { try { B(); } catch (char *ex) { cout << "A : " << ex<<endl; throw; } } int main() { try { A(); } catch (char *ex) { cout <<"main() : "<< ex << endl; } } | cs |
try문 하나에 여러 개의 catch문이 올 수 있습니다.
단, 중간에 catch가 일어나면 해당 catch문에서 exception이 끝납니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | try { A(); } catch(MemoryException& ex) { cout << "MemoryException 타입으로 잡혔음\n"; } catch(OutOfRangeException& ex) { cout << "OutOfRangeException 타입으로 잡혔음\n"; } catch(...) { cout << "그 밖의 타입\n"; } | cs |
불필요한 복사를 줄이기 위하여 예외객체는 레퍼런스로 받는 것이 좋습니다.
1 2 3 4 | catch(MyException &e){ cout <<"error message : "<< e.description<<endl<< "information : "<<e.info<<endl; } | cs |
*리소스 정리
소멸자에서의 정리
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Delete_resource { public : Delete_resource(char *p) :ptr(p) {}; ~Delete_resource() { delete[] ptr; } private : char *ptr; }; int main() { try { char *p = new char[100]; Delete_resource dr(p); throw "Exception"; } catch (char * ex) { cout << ex << endl; } } | cs |
*생성자, 소멸자에서의 정리
생성자에서 예외가 발생한 경우 : 객체가 생성되지 않은 것 = 소멸자 호출되지 않음!
예외는 그대로 던진다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Delete_resource(int arraySize) { try { // 동적으로 메모리를 할당한다. arr = new int[arraySize]; size = arraySize; throw MemoryException(this, 0); } catch (...) { cout << "여기는 실행된다!!\n"; delete[] arr; // 리소스를 정리한다. throw; // 예외는 그대로 던진다. } } | cs |
소멸자에서 예외가 발생한 경우 : 프로그램이 비정상 종료할 수 있으므로 소멸자 밖으로 throw되지 않게 한다
1 2 3 4 5 6 7 8 9 10 11 12 13 | DynamicArray::~DynamicArray() { try { // 메모리를 해제한다. delete[] arr; arr = 0; } catch(...) { } } | cs |
*bad_alloc
동적메모리 할당이 실패한 경우를 catch합니다.
1 2 3 4 5 6 | try { char *c = new char[0x7ffffff0]; } catch (bad_alloc &ex) { cout << ex.what()<<endl; } | cs |
* new, new[] 연산자를 사용하는 코드에서는 bad_alloc이 throw될 수 있다고 가정해야한다.
*auto_ptr
1 2 3 4 5 6 7 | #include <memory> using namespace std; int main() { auto_ptr<int> ptr(new int); } | cs |
#include <memory>
using namespace std;
를 사용해야하며, auto_ptr로 선언된 포인터는 자동으로 해제된다.
스파게티코드 : 코드가 꼬여있는 것
'C++' 카테고리의 다른 글
객체지향프로그래밍2 - 부실한 기초6 (1) | 2017.07.05 |
---|---|
객체지향프로그래밍2 - 부실한 기초5 (0) | 2017.07.05 |
객체지향프로그래밍2 - 부실한 기초4 (0) | 2017.07.04 |
객체지향프로그래밍2 - 부실한 기초2 (0) | 2017.06.27 |
객체지향프로그래밍2 - 부실한 기초1 (0) | 2017.06.27 |
- Total
- Today
- Yesterday
- listview
- 생활코딩
- Cell Animation
- 코딩야학
- CustomCollectionViewCell
- CollectionView
- Custom Cell
- XAML
- 문자열
- BOJ
- Grid
- DP
- WPF
- Add TapGesture
- UIView Animation
- 데이터 바인딩
- 객체
- 백준
- MVVM
- 백준온라인
- BFS
- command
- 타일링
- C++
- 스택
- dfs
- Fakebook
- 그래프
- FEED
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |