C and C++

C and C++

[C++] RAII스타일로 동작하는 lock_guard

멀티 스레드 환경에서 공유자원에 대한 접근제어를 위해 뮤텍스를 사용한다. 뮤텍스는 반드시 lock - unlock 짝으로 사용 되어야한다.그러나 짝으로 사용 되어도 개발자의 실수로 인해(조기 리턴 등) 문제를 일으킬 수 있다. 이러한 귀찮은 문제들을 한번에 해결해주는 것이 바로 lock_guard 클래스이다.lock_guard는 RAII 스타일로 구현되어 있기 때문에 자원이 할당 되면 mutex 객체를 이용하여 lock을 하고 블록을 벗어나면 자원이 해제 되면서 unlock을 한다. Defined in header template class lock_guard; Ex) int sum = 0;mutex mtx_lock; void func1(int val){ for(int i=0;i

C and C++

[C++] 자원관리 Smart Pointer (shared_ptr)

c++는 비관리 코드(unmanaged code)이기 때문에 개발자가 메모리관리를 전부 해줘야한다. 즉, 동적으로 할당 된 객체는 메모리 할당-회수를 항상 페어로 생각해야 한다.그러나 코드의 양이 커지다보면 예상치 못한 부분에서 객체의 메모리를 회수하지 못함으로인해 메모리 누수가 발생하기도 한다. java나 c#같은 언어에서는 GC가 관리해주지만 c++는 그렇지 못하기 때문에 smart pointer가 그 기능을 대신한다.memory헤더 안에 선언되어 있으며 c++11부터 사용 가능하다. smart pointer중 shared_ptr의 동작 원리는 참조 카운팅 방식이다. 즉, 객체를 참조할때마다 카운트가 올라가고 그 카운트가 0이 되는 순간 객체를 delete 시킨다. 이러한 기능을 사용하면 개발자가 굳..

C and C++

[C++] 상속을 허용하는 Base 클래스의 소멸자는 반드시 가상(virtual) 소멸자로 선언

기존에 작성된 코드나 라이브러리에서 제공하는 클래스를 상속해서 사용할 때 주의 할 점이 있다. 바로 가상소멸자의 유무이다. 이번에 공부를 하면서 알게된 사실은 클래스를 만들 때 소멸자를 가상으로 만들지 않은 것은 그 클래스를 기본(Base)클래스로 사용하지 말라는 뜻을 내포한다는 것이다.대표적인 예로 string타입, STL의 컨테이너 타입이 있다. 일단 기본클래스에 가상 소멸자로 선언되어 있지 않으면 어떤 문제가 생기는지 생각해볼 필요가 있다.다형성을 통해 기본클래스의 포인터로 파생클래스를 제어하는 경우 파생클래스의 소멸자가 호출되지 않는 문제가 발생한다.(virtual이 아니기 때문에 가상 함수 테이블이 생성되지 않아서) 아래의 코드는 메모리릭이 발생하는 코드이다.[문제 코드]class Base{pu..

C and C++

[C++] 기본으로 만들어지는 생성자,복사 생성자, 소멸자, 대입 연산자와 이를 금지하는 방법

c++에서 객체 생성시 사용자가 class에 정의하지 않았어도 기본적으로 만들어지는 함수들이 있다. 바로 기본 생성자, 복사 생성자, 복사 대입 연산자, 소멸자이다. class Test{ };처럼 빈 클래스를 만들어도 컴파일러에 의해 아래처럼 코드가 생성 된다. class Test{ private: public: Test(){}//기본 생성자 Test(const Test& copy){}//기본 복사 연산자 ~Test(){}//기본 소멸자 Test& operator=(const Test& assign){ return *this; }//기본 대입 연산자 }; 그런데 이러한 컴파일러에 의해 생성되는 코드들은 가끔 불필요할때가 있다.그래서 프로그램내에서 내가 설계한 클래스가 오직 하나만 생성되는 경우(싱글톤) ..

C and C++

[C++] 객체를 초기화 할때는 생성자 초기화 리스트를Initialize List) 사용하기

객체가 생성할될 때 가장 먼저 수행되는 것은 생성자이다. 생성되는 객체가 멤버변수를 갖고있다면(거의 대부분) 반드시 생성자에서 멤버변수들을 초기화 해주어야 한다.그런데 이러한 값들을 초기화 할 때도 보다 더 효율적인 방법이 존재한다. 바로 생성자 초기화 리스트를 사용하는 것이다. class PhoneBook{ private: std::string name; std::string phoneNum; int age; PhoneBook class가 있을 때 생성자안에서 다음과 같이 대입연산을 통해서 초기화를 진행하기 보다는 PhoneBook(const std::string& name, const std::string& phoneNum, const int age){ this->name = name; this->p..

C and C++

[C++] #define은 지양하자

c/c++에서 자주 사용 되는 #define 주로 간단한 함수나 고정 된 값이나 고정된 문자열을 만들때 사용 된다.그러나 #define은 다음과 같은 단점이 존재한다. 1. 컴파일 후 기호 테이블에 들어가지 않기 때문에 디버깅의 어려움2. 매크로함수의 경우 의도하지 않은 결과가 나올 수 있음3. 타입 안전성이 떨어짐 따라서 가능하다면 #define을 지양하고 다음과 같은 방법으로 코드를 작성하는게 좋다. #define TEST "TEST" 을 아래와 같이 변경해서 사용한다.const char * const Test = "TEST";const std::string StringTest = "TEST"; #define MAX 100을 아래와 같이 변경해서 사용한다.1.const int Max = 100;2.e..

C and C++

[C++] delete시 주의점

unmanaged 언어인 c++에서 메모리 관리는 전적으로 개발자가 해야한다.malloc이나 new로 메모리가 할당된 객체를 delete,free할 때 delete 후 NULL을 할당해 주지 않고 실수로 다시 한번 객체를 delete,free하게 된다면 segmentation fault가 발생한다. 결론적으로 template 함수로 delete와 null할당을 해주면 편할 것 같다. #include#includeusing namespace std;class Test{ };void endProgram(Test *t){ if(t){ printf("endProgram object t delete\n"); delete t; }}void readyForEnd(Test * t){ if(t){ printf("read..

개발새발
'C and C++' 카테고리의 글 목록 (3 Page)