전체 글 118

C++ static variable, static member variable, static member function

C++에서는 static 키워드란 것이 있다. static의 의미는 정적이다는 것인데 이것이 변수에도 붙을 수도 있고, 함수에도 붙을 수 있다. 그리고 클래스 내에서 static은 또 다른 의미를 갖는다. static에 관한 내가 잊고 있었거나, 처음 알게된 사실들을 정리해보고자 한다. 우선 static변수의 특징부터 복습해보자. static변수는 전역 변수와 지역 변수로서의 특징을 모두 갖는다. 1. 전역 변수처럼 프로세스가 시작할 때(main 함수 시작 전에) 메모리가 할당되고 프로그램이 종료될 때 까지 메모리가 할당된 채로 남아있다. 지역 변수는 해당 블록이 끝나면 파괴되는 것과는 대비된다. 2. static 지역 변수가 블록 안에서 선언된 것이면 그 블록 밖에서는 사용이 불가능하다. 신기하게 메모..

공부/C || C++ 2021.07.23

C++ 연산자 오버로딩(Operator overloading)

C++에서 연산자 오버로딩이란 C에서 정의하고 있는 연산자( +, -, /, *, ++, -- 등)의 동작을 다시 정의하는 것을 의미한다. 참고로 C언어는 연산자 오버로딩을 지원하지 않는다. C언어에서 정의하고 있는 연산자의 동작이란 우리가 평소에 사용하는 것과 같다. 예를 들어 +, - 연산자들은 숫자에 대해서만 정의되어 있다. 하지만 C++에서는 연산자 오버로딩을 통해 클래스 객체끼리도 그런 연산들이 가능하게 해준다. 형태는 간단하게 반환타입 operator 연산자 ( ) 방법은 2가지가 있다. 1. 멤버 함수에 의한 연산자 오버로딩 2. 전역 함수에 의한 연산자 오버로딩(클래스 정의에서 friend 선언 필요) 먼저 멤버 함수를 이용해서 연산자 오버로딩을 하는 경우를 보자 class Point { ..

공부/C || C++ 2021.07.22

함수 호출 규약(Calling convention)

함수 호출 규약이란 함수를 호출할 때 규칙이다. 함수 호출 규약이 무엇인지 알기 전에 알아야하는 용어가 몇가지 있다. 먼저 prologue/epilogue이다. 아래 첫번째 그림에서 볼 수 있듯이 함수 호출전에 이전 프레임 포인터 레지스터(ebp)를 스택에 백업해두고, 프레임 베이스 포인터를 ebp에 저장해두는 것을 부분을 prologue라고 한다. 두번째 그림 처럼 "ebp + offset" 이런식으로 보통 함수에 넘겨준 인자나 return address에 쉽게 접근할 수 있다. 호출된 함수가 끝나면 해당 함수에 대한 스택은 소멸되어야 하므로 esp를 프레임 베이스 포인터로 복귀시키고, ebp는 이전 프레임의 베이스 포인터를 다시 받고 return address로 점프하는 동작을 합쳐서 epilogue..

공부/C || C++ 2021.07.20

C++ iterator의 종류(input, output, forward, bidirectional, random access iterator)

C++에는 사실 다양한 종류의 반복자를 가지고 있다. 그리고 반복자마다 가능한 동작, 불가능한 동작이 따로 있다. 그리고 STL의 containter마다 지원되는 iterator도 달라서 숙지할 필요가 있다. 우선 카테고리는 아래와 같다. 더 큰 범주를 나타내는 iterator는 순서대로 Random Access iterator > Bidirectional iterator > Forward iterator > Input/Ouput iterator이다. 우선 모든 iterator들은 복사, 대입 연산이 가능하며 디폴트 복사생성자가 있으며 ++ 연산이 가능하다(Note: --는 Bidirection부터 된다). Input Iterator는 복사, 대입, 비교(==, !=), 역참조(*, ->를 사용하되 rv..

공부/C || C++ 2021.07.19

네임스페이스(namespace)란? std란?

C++을 맨 처음 배울 때 기계처럼 치던 코드중 하나가 using namespace std;였다. 그때 당시 이 코드 한줄이면 cout을 사용할 때 불편하게 std::를 붙이지 않아도 돼서 무조건 썼는데 사실 현업에선 이렇게 쓰지 않는다는 이야기를 듣고 쓰지 않도록 노력하고 있다. 그런데 문득 namespace와 std는 어떤걸 의미하는지 궁금해졌다. 우선 namespace는 어떤 변수나 함수의 소속을 알려주는 기능을 한다. 예를 들어서 #include namespace A { int Num = 100; } namespace B { int Num = 200; } using namespace A; using namespace B; int main() { int Num = 300; std::cout

공부/C || C++ 2021.07.19

오브젝트 풀(Object Pool)

메모리 풀에 이어서 이번에는 오브젝트 풀을 스스로 구현해보았다. 사실 구현이라고 할 만큼 뭔가 대단한 걸 한건 아니고 그냥 내가 이해한 걸 간략하게나마 코드로 짜본 것인데 뒤에 언급하겠지만 사실 성능상의 문제점도 존재하고 완벽히 정확하게 구현했는지는 잘 모르겠다. 우선 오브젝트 풀이란 프로그램 내에서 사용할 오브젝트들을 container(ex. list, vector)나 container adaptor(ex. queue, stack)에 담아 두었다가 사용자가 요청시 꺼내서 주고, 반환시 container에 다시 담아두는 것을 의미한다. 만약 동적 할당및 해제가 잦은 프로그램내에서 오브젝트 풀을 사용한다면 잦은 할당및 해제로 인한 오버헤드와 메모리 단편화도 조금 방지할 수 있다고 생각한다(사실 요즘 mem..

공부/그 외 2021.07.19

C++ 대입 연산자는 왜 void로 선언하면 안될까? 반환 타입에 왜 참조자를 붙여야 할까?

class AAA { public: int x; int y; public: AAA(int _x, int _y) : x(_x), y(_y) {}; } 위와 같은 클래스가 있을 때 대입 연산자를 어떻게 작성할까? 대부분 아래와 같이 작성 할것이다. AAA& operator=(const& AAA aaa) { x = aaa.x; y = aaa.y; return *this; } 여기서 의문점이 드는것은 두가지였다. 첫번째는 그냥 대입만 하면 되니까 void 리턴 타입으로 하면 되지 않을까? 였다. 첫번째 의문은 나와같은 의문을 가진 사람의 stackoverflow 질문에 대한 답변에서 찾을 수 있었다. 결론부터 이야기하면 void 리턴타입으로 대입 연산자를 만드는게 가능은 하지만, 그렇게 하면 A = B = C같..

공부/C || C++ 2021.07.18

Visual Studio "const char *" 형식의 값을 사용하여 "char *" 형식의 엔터티를 초기화할 수 없습니다.

char* pText = "String"; 다음과 같은 코드를 써서 컴파일하니 이런 오류가 떴다. '초기화 중' : 'const char[7]에서 'char*'(으)로 변환할 수 없습니다. 이 에러가 뜨는 원인은 Visual Studio 2017부터 준수모드로 설정하면 const char* 에서 char*로의 암시적 형변환을 허용하지 않기 때문이다(준수모드는 2번째 방법에서 바꾸는 방법을 소개). 해결 방법은 2가지가 있다. 1번째는 char*를 const char*로 바꾸면 된다. const char* pText = "String"; 2번째 방법은 Visual studio 설정을 바꿀 수 있는 상황에서 사용할 수 있다. 프로젝트 우클릭 > 속성 > C/C++ > 언어 > 준수 모드를 아니요로 바꾸면 c..

공부/그 외 2021.07.16

C++11 chrono

프로그램을 작성하다 보면 두가지 기능의 성능을 비교할 때 초단위로 혹은 그보다 정밀한 단위로 시간을 측정해야할 경우가 있다. C++ 11에서는 chrono 라이브러리에서 nanosecond단위의 시간 측정을 지원한다. 예를 들어서 피보나치 수열 함수를 동작하는데 걸리는 시간을 second, millisecond 그리고 nanosecond 단위로 측정해보자. #include #include long fibonacci(unsigned n) { if (n < 2) return n; return fibonacci(n - 1) + fibonacci(n - 2); } int main() { auto start = std::chrono::high_resolution_clock::now(); fibonacci(40);..

공부/C || C++ 2021.07.16