기타/C++: 40개의 글
[C++] 함수 템플릿 사용 template 템플릿 함수를 사용하면 컴파일러는 클라이언트(호출 측)의 함수 호출 인자 타입을 보고 템플릿 함수의 매개변수 타입을 결정하여 실제 함수인 템플릿 인스턴스 함수를 만들어 낸다. 서버 함수는 일반화된 기능만을 제공하고 클라이언트가 함수의 매개변수 타입을 결정한다.이것은 클라이언트가 타입이 다른 함수를 얼마든지 만들어내므로 대단한 확장성을 갖는다. 함수 템플릿은 함수 앞에 template 키워드를 붙이면 된다.또한, 클라이언트가 매개변수 타입을 결정하도록 타입을 일반화(T 타입)하면 된다. 함수 형식 : template void Print(T a, T b); #include using namespace std; template void Print(T a, T b){..
[C++] 함수객체 기본 예제 함수 객체(Function Object)는 함수처럼 동작하는 객체이다.함수처럼 동작하려면 객체가 operator() 를 정의해야 한다. 아래의 예제를 보면 구조체에서 operator() 연산자를 오버라이딩 하고, main에서 해당 구조체를 선언한 후 함수처럼 호출하였다. #include #include using namespace std; struct Functor1{ void operator()(int n){ cout
[C++] 생성자 타입변환과 explicit C++ 에서 클래스의 객체를 생성할 때 생성자를 사용해서 형변환을 할 수 있다. 아래와 같은 예제에서 class B 는 4개의 생성자를 가지고 있다. class A{ }; class B{ public: B() { } B(A& _a){} B(int n){} B(double d){} }; B 클래스를 생성할 때, 아래와 같이 하면 B b; // B() 생성자 호출b = a; // b = B(a) 암시적 생성자 호출 후 대입b = n; // b = B(n) 암시적 생성자 호출 후 대입b = d; // b = B(d) 암시적 생성자 호출 후 대입 위와 같이 대입을 할때, 해당 타입을 인자로 가지는 생성자가 있다면,형변환이 이루어지며 대입이 된다. 하지만 이러한 대입 ..
[C++] 스마트 포인터, operator*(), operator->() 연산자 오버로딩 스마트 포인터는 일반 포인터의 기능에 몇 가지 유용한 기능을 추가한 포인터처럼 동작하는 객체이다. 일반 포인터를 사용하면 new 연산 후 delete 연산을 호출하지 않으면 메모리 누수가 발생하여 프로그램에 심각한 문제가 된다. 또한, 사용 중에 함수가 종료하거나 예외 등이 발생하면 동적으로 할당한 메모리를 해제하지 못하는 문제가 발생한다.이런 문제들을 스마트 포인터를 사용하여 쉽게 해결할 수 있다. * 간단한 스마트 포인터 예제 class PointPtr{ Point* ptr; public: PointPtr(Point* p) :ptr(p){} ~PointPtr(){ delete ptr; } }; 위와 같이 Poin..
[C++] 연산자 오버로딩 정의 (operator) C++ 에서 클래스는 operator 를 사용하여 연산자를 오버로딩해 재정의 할 수 있다. 재정의된 연산자를 사용하여 클래스 끼리의 연산을 할 수 있다. * operator+() : 덧셈 연산자로, 해당 메소드를 오버라이딩 하면 클래스끼리 + 연산시에 동작한다. * operator++() : 단항 연산자 오버로딩, ++ 와 같은 단항 연산자를 오버로딩한다. operator++() : 전위 연산, operator++(int) : 후위 연산 #include using namespace std; class Point{ int x; int y; public: Point(int _x = 0, int _y = 0) :x(_x), y(_y){ } void print..
[C++] 파일 쓰기 예제 ofstream C++ 에서 파일 쓰기는 의 ofstream을 사용한다. DocWriter.cpp 의 Writer() 함수를 참고. main 함수를 실행하면, test.txt 파일이 생성되고 파일에 내용이 쓰여져 있다. 1. DocWriter.h #pragma once #include using namespace std; class DocWriter { public: DocWriter(); DocWriter(const string& fileName, const string& content); ~DocWriter(); void setFileName(const string& fileName); void setContent(const string& content); void Writ..
[C++] LinkedList 구현하기 예제 마지막 노드가 next 로 다시 head를 가리키도록 환형 구조로 작성했다. 노드나 리스트를 삭제할 때 delete 하여 메모리를 해제해줘야 한다. #include struct Node{ Node* prev; Node* next; void* data; }; struct List{ Node* head; }; List* createList(){ Node* head = new Node; head->prev = head; head->next = head; head->data = 0; List* list = new List; list->head = head; return list; } void insertNodeAfter(Node* node, void* data){ N..
[C++] 왜 포인터는 하나의 타입밖에 가리킬 수 없는가? 포인터는 어떠한 변수를 가리키는 주소값을 가진 변수이다. 그렇다면 데이터를 가지고 있는 것도 아니고 주소값을 가지고 있는 것인데, 왜 한가지 타입밖에 가리킬 수 없을까? 하나의 포인터로 다양한 타입을 가리킬 수 있으면 더 자유롭게 사용할 수 있을텐데.. 그것은 포인터가 가리키고 있는 변수의 타입을 알 수 없기 때문이다. 변수의 타입을 알 수 없으면, 포인터가 가리키는 변수의 값을 가져올 때 몇 바이트인지 알 수가 없다. 따라서 포인터가 가리키는 변수의 타입을 알기 위하여, 포인터 변수는 타입이 지정되어 있으며, 해당 타입의 변수만 가리킬 수 있다. 예외적으로 void* 포인터는 모든 타입을 가리킬 수 있다.하지만 지금 가리키고 있는 변수가 어떤 ..
[C++] 비트 연산과 쉬프트 (>>,
[C++] 문자열 입력 getline()과 버퍼오버플로우 문자열을 입력받을 때, cin >> 을 보통 사용한다. 하지만 cin 으로 문자열을 입력받을 때 문제점들이 있다. (1) 버퍼 오버플로우 cin으로 입력받는 배열의 크기를 넘어서는 문자열을 cin 을 통해 입력받으면, 배열의 크기를 넘어 다른 변수 소유의 메모리에 덮어쓰게 된다.이것은 의도하지 않은 변경을 발생시키며, 심각한 문제를 일으킬 수 있다.이것을 버퍼 오버 플로우 라고 한다. (2) cin을 사용한 연속된 문자열 입력시 공백 처리 cin 을 연속으로 사용하여 2번의 문자열을 받을 때 공백을 만나면 다음 cin의 변수로 데이터가 넘어간다.예를들어, I'm Hyeon 을 입력하면, I'm 은 첫번째 변수에 Hyeon은 두번째 변수에 들어간다...