C Hello World include stdafx h include iostream










































![복사 생성자(Copy Constructor) [2] • 내부의 포인터 주소 자체가 복사됨 My. String str 1; 복사 생성자(Copy Constructor) [2] • 내부의 포인터 주소 자체가 복사됨 My. String str 1;](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-43.jpg)
![복사 생성자(Copy Constructor) [3] class My. String { public: My. String() : pointer(nullptr) {} 복사 생성자(Copy Constructor) [3] class My. String { public: My. String() : pointer(nullptr) {}](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-44.jpg)






![가상함수(Virtual Function) [2] class Shape { public: double get. Size(){ return 0. 0 f; 가상함수(Virtual Function) [2] class Shape { public: double get. Size(){ return 0. 0 f;](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-51.jpg)






![Function Template [2] template< typename value_type > void Swap( value_type& t 1, value_type& t Function Template [2] template< typename value_type > void Swap( value_type& t 1, value_type& t](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-58.jpg)
![Function Template [3] * 캐스팅 함수의 정의 template< typename To, typename From > To Function Template [3] * 캐스팅 함수의 정의 template< typename To, typename From > To](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-59.jpg)
![Function Template [4] • 템플릿 특수화(Template Specialization) – 어떤 type에 대해서는 특별하게 처리하고 싶은 Function Template [4] • 템플릿 특수화(Template Specialization) – 어떤 type에 대해서는 특별하게 처리하고 싶은](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-60.jpg)











![std: : map<key_type, T> • ‘사전’ 형식의 자료 구조 • data[“key”] : 검색 뿐만 std: : map<key_type, T> • ‘사전’ 형식의 자료 구조 • data[“key”] : 검색 뿐만](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-72.jpg)













![try-catch 구문 try{ int *buffer = 0; //new int[N]; if (buffer == nullptr) throw try-catch 구문 try{ int *buffer = 0; //new int[N]; if (buffer == nullptr) throw](https://slidetodoc.com/presentation_image/2ca3ad3f2ece9b23d9be9a14e49a61c5/image-86.jpg)

































- Slides: 119
C++ Hello World 프로그램 #include "stdafx. h" #include <iostream> using namespace std; #include "stdafx. h" #include <stdio. h> int _tmain(int argc, _TCHAR* argv[]) { cout << "Hello World" << endl; int x; cin >> x; int _tmain(int argc, _TCHAR* argv[]) { printf("Hello Worldn"); int x; scanf("%d", &x); return 0; } C에서의 구현 • 다른점? #include <iostream>? using namespace? cout? >>? <<? 4
C++: Multi-paradigm Programming Language Functional Programming C++ Procedural Programming Object-Oriented Programming Generic Programming Template Metaprogramming 5
C++: Procedural Programming • 프로그램의 상태를 직접적으로 변화시키는 명령들로의 구성 • 처리해야 할 작업을 순차적으로 나열 – 전통적인 방식 • 특성 Direct assignments, Common data structures, Global variables, Local variables, Iteration, Modularization 6
C++: Object-Oriented Programming • 객체(Object) = 데이터(특성; Attributes) + 코드(행동 양식; Behavior) • 프로그램의 상태를 ‘객체’의 미리 정의된 Behavior를 통해서만 조작 함 • GUI로 인해 엄청나게 증가한 소프트웨어의 복잡성을 다루기 위해 ‘ 모듈화’ 또는 ‘재사용성’ 강조 • 특성 Objects, Classes, Methods, Message Passing, Information Hiding, Data Abstraction, Encapsulation, Polymorphism, Inheritance, Serialization 7
C++: Functional Programming • 프로그램 내부에 상태(state)가 형성되는 것을 피하기 위 해 프로그램을 수학적 함수의 결합으로 나타낸다. • 병렬 처리/ 분산 환경: 필수적으로 다가온 동시성 다루기 – ‘부작용’이 없어야 함 • 특성 Lambda calculus (C++11) Higher order functions Closures Recursion No side effects C Function pointer C++ Function object C++11 Lambda function Functional Programming의 지원 8
C++: Template Metaprogramming • C++의 template 기능은 또 다른 한 언어로 봐도 무방… 11
Memory Management in C++ • new, delete 연산자의 도입 C에서의 heap memory 할당/해제 C++에서는 new, delete 연산자 사용 14
Const Modifier // compiler error = expression must be a modifiable value char* str 1 = "hello 1"; str 1[0] = 'y'; // access violation str 1 = "world 1"; const char* str 2 = "hello 2"; str 2[0] = 'y'; // compile error str 2 = "world 2"; char* const str 3 = "hello 3"; str 3[0] = 'y'; str 3 = "world 3"; // compile error const char* const str 4 = "hello 4"; str 4[0] = 'y'; // compile error str 4 = "world 4"; // compile error 22
OOP Keywords • • Encapsulation Information Hiding Inheritance Polymorphism 23
Polymorphism Shape draw() get. Size() Rectangle draw() get. Size() Circle draw() get. Size() Triangle draw() get. Size() • Polymorphism (다형성)은 다른 type에 대해 같은 interface를 제공한다. • 위의 예는 Sub Typing이라고도 부름. Rectangle, Circle, Triangle은 Shape의 draw와 get. Size라는 인터페이스를 상속받지만 각자 하는 일 이 다르다. • 다형성의 장점은 객체를 한꺼번에 다룰 수 있다는 점. Shape로 통일 되어 있지 않을 때 모든 Rectangle, Circle, Triangle의 넓이의 합을 구 하려면? • Function Overloading도 넓게는 Polymorphism의 개념에 포함됨 27
Class 선언하기 class Class. Name : public Base. Class. Name 상속이 필요한 경우에만 { public: Member Variable Some. Type public. Member. Var; void foo(){ Member Function /* some defines */ } void foo 2(); /* elsewhere */ 나중에 다른 곳에서 정의해줘야 함 protected: Some. Type protected. Member. Var; private: Some. Type private. Member. Var; }; • 앞으로 Class. Name이라는 type을 추가한다는 의미임! • 실제로 클래스를 사용하기 위해선 인스턴스(instance)를 생성해야함 30
Static Member Variable • 클래스는 type을 의미하고 각 member variable은 독립 적임 • 그러나 Static 키워드를 추가하면 클래스 type에 대해 유 class Countable. Class { public: 일한 변수를 할당할 수 있음 Countable. Class() { std: : cout << "인스턴스 생성 " << this << std: : endl; count++; } ~Countable. Class() { std: : cout << "인스턴스 소멸 " << this << std: : endl; count--; } int get. Count() const { return count; } private: static int count; }; int Countable. Class: : count = 0; int _tmain(int argc, _TCHAR* argv[]) { Countable. Class instance. A; { Countable. Class instance. B; std: : cout << instance. B. get. Count() << std: : endl; } std: : cout << instance. A. get. Count() << std: : endl; return 0; } 34
Const Member Variable class Countable. Class { public: Countable. Class() : type. Code(456) { /* 생성자 */ } private: static const int static. Type. Code = 123; const int type. Code; }; • 멤버 변수의 성격이 상수일 때 const 키워드를 붙인다. • Static 키워드를 붙이면 바로 초기화 가능(type이 int일 때만) • 일반 const member variable은 생성자의 초기화 리스트에서 초기화 35
Mutable Member Variable • Const 한정자가 붙은 함수는 member variable의 값을 수정할 수 없다! class Countable. Class { public: /* 생략 */ int get. Count() const { call. Count++; return count; } private: static int count; int call. Count; }; 컴파일 에러: Expression must be modifiable L-Value • 그렇다고 get. Count()에 const를 뺄 수도 없음 • Member variable 앞에 mutable 넣으면 해결! mutable int call. Count; 36
멤버 초기화 리스트(Member Initialization List) • 초기화 리스트의 순서는 아무 상관 없다. class Type 1 { public: Type 1(int a){ std: : cout << "Type 1 초기화" << std: : endl; } }; class Type 2 { public: Type 2(int b){ std: : cout << "Type 2 초기화" << std: : endl; } }; class Type 3 { public: Type 3(int c){ std: : cout << "Type 3 초기화" << std: : endl; } }; class Member. Initialization. Test { public: Member. Initialization. Test() : type 1(0) , type 2(0) , type 3(0) { } private: Type 2 type 2; Type 3 type 3; Type 1 type 1; } test; • 실행 결과는? • Class 안에서 정의된 순서에 의해 초기화가 진행됨 38
레퍼런스 멤버의 초기화 class Manager { /* some definitions */ }; class Test. Object { public: private: Manager& manager; } test. Object; 멤버 변수로 reference 변수 가능함 단, 초기화 리스트에서 초기화하지 않으면 컴파일 에러(no appropriate default constructor available) class Test. Object { public: Test. Object(Manager& manager_) : manager(manager_) {} private: Manager& manager; } test. Object(Manager()); 실제로는 올바른 객체를 넣어야겠죠? 39
상속된 클래스에서의 생성자/ 소멸자 class Base { public: Base(){ std: : cout << "Base 생성" << std: : endl; } ~Base(){ std: : cout << "Base 소멸" << std: : endl; } }; int _tmain(int argc, _TCHAR* argv[]) { Derived instance; return 0; } 실행 결과 class Derived : public Base { public: Derived() { std: : cout << "Derived 생성" << std: : endl; } ~Derived(){ std: : cout << "Derived 소멸" << std: : endl; } }; 41
복사 생성자(Copy Constructor) • 필요성 – Implicit Copy의 문제점 class My. String { public: void allocate(){ pointer = new char[16]; // initial buffer } /* for debug */ void set. Pointer(char* pointer_) { pointer = pointer_; } char* get. Pointer() const { return pointer; } private: char* pointer; }; 42
복사 생성자(Copy Constructor) [2] • 내부의 포인터 주소 자체가 복사됨 My. String str 1; My. String str 2; * str 1 그리고 str 2가 같은 주소를 가리키므로 str 1을 수 정하면 str 2에도 반영됨 str 1. allocate(); str 2 = str 1; // Implicit Copy std: : cout << "str 1. get. Pointer() = " << (int)str 1. get. Pointer() << std: : endl; std: : cout << "str 2. get. Pointer() = " << (int)str 2. get. Pointer() << std: : endl; str 1 • pointer H E L L O W O R L D str 2 • pointer 43
복사 생성자(Copy Constructor) [3] class My. String { public: My. String() : pointer(nullptr) {} My. String(const My. String& copy_from_me){ this->allocate(); // 적당한 공간 할당 후 // copy_from_me 에서부터 문자열 복사하기 } … 생략 … My. String str 1; str 1. allocate(); My. String str 2(str 1); 44
복사 대입 연산자 = My. String& operator=(const My. String& copy_from_me){ this->allocate(); // 적당한 공간 할당 후 // copy_from_me 에서부터 문자열 복사하기 return *this; // 자기 자신을 리턴함 } (생각해봐야 할 점) self-assignment (ex) str 1 = str 1; 45
Getter and Setter – 노가다? 연락처 Class Member Variables • 이름 string get. Name() const void set. Name(const string& name) • 그러나 멤버 변수가 외부로 노출되어 있을 시, • 값이 한번 바뀌면 언제 바뀌 었는지 추적하기가 너무 어 렵다. • 전화번호 string get. Phone() const void set. Phone(const string& phone) • Getter/ Setter 만들면, 언제 어디서 값이 바뀌는지 추적 이 용이 • 이메일 string get. Email() const void set. Email(const string& email) 46
상속 시 이름이 겹칠 때 class Conflict. Base { public: int X; }; class Conflict. Derived : public Conflict. Base { public: int X; void Print. X(){ std: : cout << X << std: : endl; } void Print. Base. X(){ std: : cout << Conflict. Base: : X << std: : endl; } }; 같은 이름이 있으면 자기 자신의 멤버 변수가 우선하지만 부모 클래스의 X가 필요한 경우는 위처럼 범위를 지정해줄 수 있다. 48
가상함수(Virtual Function) • A function or method whose behavior can be overridden with an inheriting class by a function with the same signature • 부모 클래스와 자식 클래스가 같은 형태의 함수(리턴값, 매개변수 목록, 함수 이름)을 갖고 있을 때, 자식 클래스 의 함수가 실행된다. 50
가상함수(Virtual Function) [2] class Shape { public: double get. Size(){ return 0. 0 f; } }; class Rectangle : public Shape { public: Rectangle(double width, double height) : width(width), height(height) {} double get. Size(){ return width * height; } private: double width; double height; }; • Rectangle을 Shape로도 다루고 싶은데. . . Rectangle rectangle(10, 20); std: : cout << "Rectangle 1 = " << rectangle. get. Size() << std: : endl; Shape& shape(rectangle); std: : cout << "Shape (Rectangle 1) = " << shape. get. Size() << std: : endl; class Circle : public Shape { public: Circle(double radius) : radius(radius) {} double get. Size(){ return 3. 141592 * radius; } private: double radius; }; • 원래 의도는 Rectangle: : get. Size()를 호출 하는 것이었지만, Shape: : get. Size()가 • Shape *ptr = &rectangle; ptr->get. Size(); 도 마찬가지 • 게다가 ptr에는 circle이 대입될 수도 있고 현 상황에서는 실행 중에 타입 을 알 수 있는 방법이 전혀 없기 때문이다. 51
Polymorphism의 응용 • Abstract Class (혹은 Interface Class) class Shape { public: Shape() {} virtual double get. Size() = 0; virtual void draw() = 0; }; class Rectangle : public Shape { public: Rectangle(double width, double height) : width(width), height(height) {} double get. Size(){ return width * height; } void draw() { std: : cout << "The rectangle is drawed : " << width << "x" << height << std: : endl; } private: double width; double height; }; class Circle : public Shape { public: Circle(double radius) : radius(radius) {} double get. Size(){ return 3. 141592 * radius; } void draw() { std: : cout << "The circle is drawed : " << radius << std: : endl; } private: double radius; }; for ( int i = 0; i < _countof(shapes); ++i ) { std: : cout << shapes[i]->get. Size << std: : endl; shapes[i]->draw(); } 54
Function Template [2] template< typename value_type > void Swap( value_type& t 1, value_type& t 2 ){ value_type t = t 1; t 1 = t 2; t 2 = t; } Rectangle rec 1(10, 20); Rectangle rec 2(30, 40); rec 1. draw(); rec 2. draw(); Swap(rec 1, rec 2); rec 1. draw(); rec 2. draw(); • value_type에 = 연산만 잘 정의되어 있으면 어떤 type에 대해서도 swap 가능 • 컴파일러의 타입 추론 -Swap<Rectangle>(rec 1, rec 2); 으로 불러도 되나 Swap(rec 1, rec 2); 도 문제 없음 • 사용된 모든 종류의 value_type에 대한 코드를 컴파일러에서 생성해준다. (Implicit Instantiation) 58
Function Template [3] * 캐스팅 함수의 정의 template< typename To, typename From > To my_cast( const From& from ){ std: : cout << typeid(From). name() << " to " << typeid(To). name() << std: : endl; return static_cast<To>(from); } char a = 'a'; int a_casted = my_cast<int>(a); 컴파일러가 typename From은 알아서 추론해줌 59
Function Template [4] • 템플릿 특수화(Template Specialization) – 어떤 type에 대해서는 특별하게 처리하고 싶은 경우가 있을 때 template<> long my_cast( const char& from ){ std: : cout << "[long] 재정의된 캐스팅" << std: : endl; return static_cast<long>(from); } * char -> long 은 다르게 처리하고 싶을 때(…) char a = 'a'; int a_casted = my_cast<int>(a); long b_casted = my_cast<long>(a); 60
Class Template • Function Template와 마찬가지로 클래스에서도 template을 제공 template<typename T> class My. Stack{ public: void Push(const T& item); T Pop() { return T(); } private: T* data; }; 보통 template 코드는 클래스 선언 내에 정의되는 경우가 많다. * 클래스 템플릿 선언과 별도로 정의할 수도 있 다. template<typename T> void My. Stack<T>: : Push(const T& item){ std: : cout << "push " << item << std: : endl; } My. Stack<int> int. Stack; My. Stack<double> double. Stack; My. Stack<Shape*> shape. Pointer. Stack; int. Stack. Push(123); double. Stack. Push(456. 0); shape. Pointer. Stack. Push(nullptr); 62
Template 관련 에러 메시지 • 에러 메시지 읽기// T의 크기가 4바이트가 아니면 컴파일 에러가 발 생하도록 하였음(C++11) void Push(const T& item) { static_assert( sizeof(T) == 4, "The size of T should be 4 bytes. " ); } 1>h: homenoeldocumentspersonaldevworktemptutorial 1. cpp(149): error C 2338: The size of T should be 4 bytes. 1> h: homenoeldocumentspersonaldevworktemptutorial 1. cpp(149) : while compiling class template member function 'void My. Stack<T>: : Push(const T &)' 1> with 1> [ 1> T=double 1> ] 1> h: homenoeldocumentspersonaldevworktemptutorial 1. cpp(162) : see reference to function template instantiation 'void My. Stack<T>: : Push(const T &)' being compiled 1> with 1> [ 1> T=double 1> ] 1> h: homenoeldocumentspersonaldevworktemptutorial 1. cpp(158) : see reference to class template instantiation 'My. Stack<T>' being compiled 1> with 1> [ 1> T=double 1> ] 63
STL 컨테이너(Container) • Sequence Container • Vector 동적 배열 • List 순서가 있는 리스트 • Deque 양 끝에서 입력과 출력 가능 • String 문자열 • Associative Container • Map 사전과 같은 구조 <key, value> • Multi Map 중복 key를 허용 • Set 집합 <key> • Multi Set 중복 key를 허용 • Adaptor Container • Stack • Queue • Priority Queue 65
std: : deque<T> #include <deque> • 벡터에서 push_back(val), pop_back()에 앞에서도 추가/삭제 : push_front(val), pop_front() • queue<T>, stack<T>는 내부적으로 deque<T>를 사용 하도록 되어있음 71
std: : map<key_type, T> • ‘사전’ 형식의 자료 구조 • data[“key”] : 검색 뿐만 아니라 value_type의 초기값이 들어가므로 단순 검색에는 find 함수를 이용해야 함 string tmp; map< string, int > count; while (true){ cin >> tmp; if (tmp == "q") break; count[tmp]++; } a friend in need is a friend indeed a : 2 friend : 2 in : 1 indeed : 1 is : 1 need : 1 for (map<string, int>: : const_iterator itr = count. begin(); itr != count. end(); ++itr){ cout << itr->first << " : " << itr>second << endl; } cout << count[“smith”] << endl; 없는 단어이므로 0이 나오겠지만 <“smith”, 0>이라는 항목으로 tree에 추가가 된다. 72
std: : map<key_type, T> • 내부 구현은 Red Black Tree. 임의의 키에 대해서 O(log N)의 접근 • Find 함수로 검색 map< string, int > score; score["dog"] = 96; score["cat"] = 90; string name; cin >> name; map< string, int >: : const_iterator itr = score. find(name); if (itr != score. end()) { cout << itr->second; } else{ cout << "not found" << endl; } 73
Container의 올바른 선택 Container Random Access Insert Erase Find Sort list N/A C C N N log N vector (deque) C C~N N N log N set C log N C map log N C • 중복된 key를 허용하고 싶을 때 multiset, multimap • 모든 경우에 대해 최적의 컨테이너는 없고 상황에 따라 효율적인 컨테이너 를 골라 써야 한다. 74
반복자(Iterator) • 컨테이너를 순회하면서 모든 원소 출력 typedef std: : vector<int> Container; Container int. Array; int. Array. push_back(1); int. Array. push_back(2); int. Array. push_back(3); • 컨테이너의 종류가 다른 것(list, deque)으로 바뀌어도 아래 코드는 변 하지 않는다 for (Container: : iterator itr = int. Array. begin(); itr != int. Array. end(); itr++) { cout << *itr << endl; } • 검색이나 단순 순회처럼 컨테이너에 들어있는 원소 값을 바꾸지 않는다면 상수 반복자를 사용할 수 있다. Iterator 대신 const_iterator를 쓴다. begin -> cbegin, end -> cend 76
Operator Overloading 표현식 멤버 함수가 아닐 때 예제 @a a. operator@() operator@(a) !std: : cin std: : cin. operator!() a@b a. operator@(b) operator@(a. b) std: : cout << “hello world” std: : cout. operator<<(const std: : string&) a=b a. operator=(b) X std: : string s; s = “abc”; std: : string. operator=(const char*) a[b] a. operator[](b) X std: : map<int, int> m; m[1] = 2; m. operator[](int) a-> a. operator->(b) X std: : unique_ptr<…> ptr; ptr->foo(); ptr. operator->() a@ a. operator@(0) operator@(a, 0) std: : vector<…>: : iterator i; i++; i. operator++(0); 77
Operator + Overloading class Complex. Number{ public: Complex. Number operator+(const Complex. Number& e){ return Complex. Number(this->real + e. real, this>imaginary + e. imaginary); } • 복소수 끼리 더하는 연산 • A @ B 형태이고, 멤버 함수에서 operator@(B) 형태로 overload 가능 78
Operator << Overloading class Complex. Number{ public: Complex. Number(double real_, double imaginary_) : real(real_), imaginary(imaginary_) {} friend ostream& operator<< (ostream& os, Complex. Number& a){ os << a. real << "+" << a. imaginary << "i"; return os; } /* 생략 */ private: double real; double imaginary; }; Complex. Number c 1(1, 2); cout << c 1 << endl; // 1+2 i * 의의 : stream만 잘 정의되면 화면 출력이 든, 파일이든, 아니면 네트워크든 모두 같은 양식으로 보낼 수 있다. friend 를 쓴 이유는 클래스의 멤버는 아니지만 클래스의 보호된 멤버에 접근하기 위해서임(특수한 경우에만 사용해야함) 79
Operator() Overloading • Function Object 구현 시 사용(Functor라고도 불림) • STL의 많은 부분에서 사용되고 있음 // TEMPLATE FUNCTION sort template<class _Ran. It> inline void sort(_Ran. It _First, _Ran. It _Last) { // order [_First, _Last), using operator< _STD sort(_First, _Last, less<>()); } // TEMPLATE STRUCT less template<class _Ty = void> struct less : public binary_function<_Ty, bool> { // functor for operator< bool operator()(const _Ty& _Left, const _Ty& _Right) const { // apply operator< to operands return (_Left < _Right); } }; 80
알고리즘(Algorithm) • for_each, find_if, count_if, … • copy, swap, transform, replace, fill, generate, remove, unique, reverse, rotate, shuffle, … • partition, sort, nth_element, … • binary_search, … • min, max, … • next_permutation, prev_permutation, … • http: //www. cplus. com/reference/algorithm/ 81
std: : for_each • std: : for_each(시작 iterator, 끝 iterator, 함수); struct Print. Int. Element{ void operator()(int& elem){ cout << elem << endl; } }; std: : for_each(int. Array. begin(), int. Array. end(), Print. Int. Element()); <Function object의 활용> std: : for_each(int. Array. begin(), int. Array. end(), [](int& elem){ cout << elem << endl; } ); <C++11에서 더 간결해진 문법> Algorithm 함수를 사용하여 코드를 만든 의도가 더 잘 드러나도록 할 수 있다. 82
std: : sort vector<int> data; data. push_back(2); data. push_back(3); data. push_back(1); sort(data. begin(), data. end()); // 오름차순 정렬 struct Desc{ bool operator()(const int& e 1, const int& e 2){ return e 1 > e 2; } }; sort(data. begin(), data. end(), Desc()); // 내림차순 정렬 Predicate 함수를 갈아끼우는 방식으로 여러 가지 조건 구현 가능 83
Algorithm 기타 예제 transform 대문자로의 변환 string msg = "The STL algorithms are generic because. . . "; transform(msg. begin(), msg. end(), msg. begin(), toupper); next_permutation 순열 생성 vector<int> a(3); for (size_t i = 0; i < a. size(); ++i) a[i] = i + 1; do { copy(a. begin(), a. end(), ostream_iterator<int>(cout, "t")); cout << endl; 1 2 3 } while (next_permutation(a. begin(), a. end())); 1 3 2 2 1 3 2 3 1 2 3 2 1 Press any key to continue. . . 84
try-catch 구문 try{ int *buffer = 0; //new int[N]; if (buffer == nullptr) throw exception("allocation failed"); int *buffer_2 = 0; //new int[N]; if (buffer_2 == nullptr) throw bad_exception(); throw 123; } catch (bad_exception& e){ cerr << e. what() << endl; } catch (int error. Number){ cerr << error. Number << endl; } catch (. . . ){ cerr << "unknown exception" << endl; } • try 블록 안의 명령들을 실 행하다 throw 문에서 예외 가 발생하면 catch로 넘어 가 예외를 처리한다. • catch(…)은 catch 구문에 서 받기로 지정하지 않은 type의 예외가 들어왔을 때의 처리다. • C++에서 정의된 예외만 핸들링 가능 • 만약 catch해주는 코드가 없으면 함수를 바로 빠져 나가 그 상위 함수에서 찾 는다. • Main까지 가도 없으면 프 로그램이 종료됨 86
RTTI (Runtime Type Information) • 프로그램 실행 중 객체의 type을 알 수 있도록 함 • dynamic_cast, typeid 연산자, type_info 클래스 class Super { public: virtual ~Super(){} }; class Base : public Super {}; class Derived : public Base {}; Super super; Base base; Derived derived; cout cout << << << Super* p = &derived; cout << typeid(*p). name() << endl; Super? or Derived? typeid(super). name() << endl; typeid(base). name() << endl; typeid(derived). name() << endl; typeid(int*). name() << endl; class Super class Base class Derived int * Press any key to continue. . . 87
형변환(Casting) • Implicit casting (암시적 캐스팅) • Explicit casting (명시적 캐스팅) int i = 10; char c = i; // implicit cast char d = (char)i; // explicit cast (C style) char e = char(i); // explicit cast (C++ style) • C++의 세분화된 casting – – static_cast dynamic_cast reinterpret_cast const_cast 88
dynamic_cast • 모호한 포인터에 대한 변환 • RTTI(Runtime Type Information) 정보를 확인하므로 – 추가적인 오버헤드. • 실패 시 null 을 리턴 Rectangle* -> Shape*나 Circle* -> Shape*는 문제가 없음 Shape 그렇다면 Shape*를 Rectangle*로 변환할 수 있는지? (down-casting) Rectangle Circle 91
reinterpret_cast • • 포인터끼리 아무런 제약없이 변환 정수형 <-> 포인터 const_cast • 포인터의 상수성을 제거하는 데 사용 int data = 301; int* ptr = &data; double PI = 3. 14; const double* ptr = &PI; cout << *ptr << endl; //cout << *static_cast<double*>(ptr) << endl; cout << *reinterpret_cast<double*>(ptr) << endl; // *ptr = 3. 1415; // expression must be a modifiable value 301 -9. 25596 e+061 Press any key to continue. . . *const_cast<double*>(ptr) = 3. 1415; cout << *ptr << endl; 92
RAII(Resource Acquisition Is Initialization) class _ifstream{ public: _ifstream(const char*) { cout << "open!" << endl; } virtual ~_ifstream(){ cout << "close!" << endl; } }; 실제 ifstream의 동작을 보기 어려우므로(…) try{ _ifstream ifs("input. txt"); /* some works */ throw exception(); open! close! Unknown exception Press any key to continue. . . } catch (exception& e){ cerr << e. what() << endl; } Scope에서 벗어나는 순간 무조건 소멸자가 불리므로 앞 예제에서 하지 못했던 리소스 반환 절차를 진행할 수 있다. 94
Smart Pointer • new 와 delete의 짝을 맞춰주는 일도 항상 골칫거리 • Smart Pointer (Reference Counted Pointer) – 포인터 객체가 생성될 때 +1, 소멸될 때 -1 – 소멸자에서 Count값이 0이 되면 delete한다. – 포인터끼리 복사가 일어나면 +1 { shared_ptr<_ifstream> p(new _ifstream("input. txt")); // ref = 1 { Config. Loader loader(p); // ref = 2 } // ref = 1 } // ref = 0 -> delete • Overhead : 카운터를 저장할 공간(4 bytes? ) 95
Smart Pointer • Reference Counted가 잘못 동작하는 경우 • Type A인 객체가 Smart Pointer<Type B>를 들고 있고 • Type B인 객체가 Smart Pointer<Type A>를 들고 있을 때 • 즉, cyclic 관계가 형성될 때 Reference Count가 제대로 되지 않는다. Shared_ptr<A> ref = 1 shared_ptr<B> ref = 1 B가 생성되면서 A를 참조 Shared_ptr<A> ref = 2 shared_ptr<B> ref = 1 A가 소멸되나 ref=2에서 ref=1이므로 delete a; 는 호출되지 않는다 Memory leak 발생 B가 먼저 소멸 Shared_ptr<A> ref = 2 shared_ptr<B> ref = 0 delete b; 96
SVN 구성 • SVN 서버 – http: //www. visualsvn. com/ 에서 무료로 다운로드 가능 • SVN 클라이언트 – http: //tortoisesvn. net/ - 탐색기와 연동됨 • Visual Studio 플러그인 – Ankh. SVN https: //ankhsvn. open. collab. net/ 98
Git 구성 • 로컬에서만 작업하면 Git 서버 필요 없음 • 무료 원격 저장소(개인용) – Bitbucket https: //bitbucket. org/ • Git 클라이언트 – Source. Tree http: //www. sourcetreeapp. com/ – Tortoise. Git https: //code. google. com/p/tortoisegit/ • 보다 친절한 설명서(Googling: git 설명서) – http: //rogerdudler. github. io/git-guide/index. ko. html – http: //git-scm. com/book/ko/ 99
Visual Studio Debug메뉴 103
Debugging 예제 – is_prime bool is_prime(int n){ int cnt = 0; for (int i = 1; i*i < n; ++i){ if (n%i == 0){ cnt++; if (cnt>1) return false; } } if (cnt == 1) return true; return false; } int _tmain(int argc, _TCHAR* argv[]) { for (int i = 1; i < 100; ++i){ if (is_prime(i)) cout << i << "t"; } cout << endl; return 0; } 2 3 4 5 7 9 11 13 17 19 23 25 29 31 37 41 43 47 49 53 59 61 67 71 73 79 83 89 97 Press any key to continue. . . 처음부터 Step by Step 으로 들어 가면 너무 오래 걸리니까 Is_prime 함수의 첫번째 줄에 Conditional Break를 건다. 즉, n = 9일 때 break를 걸어보자 104
Breakpoints Window 105
Call Stack (@ Stack Overflow) 110
Show Includes 옵션으로 검사하기 116
Output Window 출력 메시지(앞부분) 1> 1> 1> 1> 1> 1> 1> Note: Note: Note: Note: Note: Note: Note: including including including including including including including file: file: file: file: file: file: file: r: debuggingstdafx. h r: debuggingtargetver. h C: Program Files (x 86)Microsoft SDKsWindowsv 7. 0 AincludeSDKDDKVer. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludestdio. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludecrtdefs. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludesal. h c: program files (x 86)microsoft visual studio 10. 0vcincludecodeanalysissourceannotations. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludevadefs. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeswprintf. inl c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludetchar. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludecrtdefs. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludewtime. inl c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeiostream c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeistream c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeostream c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeios c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludexlocnum c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeclimits c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeyvals. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludecrtdefs. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludeuse_ansi. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludelimits. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludecrtdefs. h c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludecmath c: Program Files (x 86)Microsoft Visual Studio 10. 0VCincludemath. h 117