static은 link의 개념과 scope block의 개념으로 구분되는데 static - link의 개념은 간단하게 internal linkage를 의미하고 아래의 링크를 참고하면 된다https://motivelessstudy.tistory.com/313 static - scope block의 개념은 일반적인 static과 static member variable/function로 구분된다 1) 일반적인 static 초기화가 단 한 번만 실행된다#include void func(){ static int a = 0; std::cout 2) static member variable/function모든 클래스가 하나의 static 변수를 공유한다#include class A{public: int i; st..
static은 link의 개념과 scope block의 개념으로 구분되는데 여기서는 link의 개념을 의미한다 extern은 external linkage이고 static은 internal linkage이다 extern은 다른 어딘가 정의돼있을 것이라고 알려주는 용도로 사용된다 이는 외부와 link해서 사용하도록 하는 것이다 // main.cpp #include extern int a; int main() { std::cout
# std::string의 size std::string의 size는오래된 컴파일러의 라이브러리에서는 8byte모던 STL에서는 32byte or 40byte를 차지한다 # std::string의 내부 구조 8byte인 경우는스택에 std::string의 8바이트 주소를 가지고 있고힙에 "abc"가 있고 끝 부분에 size와 capacity가 포함된다 32byte or 40byte인 경우는스택에 std::string의 8바이트 주소와 size, capacity, 그 외의 정보가 들어가고힙에 "abc"가 있다 # std::string의 문제자주 쓰이는 변수 타입들은 대부분 스택에 들어간다그러나 std::string은 힙에 할당이 되기에속도와 효율의 문제가 발생한다 이를 해결하기 위해서32byte가 std..
OOP의 문제는Base 클래스를 뜯어고쳐야 하는 상황이 오면,Derived 클래스들도 모두 뜯어고쳐야 한다는 것이다 또한, 특정한 Derived 클래스들을 Base 클래스로부터 분리해야 하는 경우에도굉장히 복잡해지며 유지 보수가 어려워 진다 따라서, 아래와 같은 Dynamic function binding이 정말 필요한지 생각을 해봐야 한다 Animal* animal; if (rat)// Dynamic function binding { animal = new Cat(); } else if(thief) { animal = new Dog(); } Dynamic function binding이 필요 없다면상속 없이 클래스를 만들고 각자의 멤버 변수와 함수를 이용하는 것이유지 보수가 더욱 좋다
Virtual function은 dynamic function binding이며 런타임 중 바인딩이 된다 function overloading은 static function binding이며 컴파일 시 바인딩이 된다 virtual 키워드가 사용되면 virtual table pointer (8바이트)가 추가되고 그에 맞게 padding이 진행되어 사이즈가 결정된다 virtual table pointer를 타고 가면 나오는 virtual table에 해당하는 클래스의 멤버 함수들이 저장되어 있기 때문에 부모 클래스로 자식을 생성하더라도 자식 멤버 클래스가 실행이 된다 또한, 아래의 코드에서 볼 수 있듯이 런타임 중 발생하는 상황에 따라서 바인딩이 달라질 수 있다 #include #include class B..
아래의 글을 참고하면 된다 https://motivelessstudy.tistory.com/209 [C] 바이트 정렬 바이트 정렬 요구사항 시스템 별로 메모리에 효율적으로 접근하기 위해서 n 바이트 배수인 시작 주소에서만 메모리 접근이 가능하게끔 한다 예를 들어, x86 시스템은 4바이트 단위로 읽어오고 4 motivelessstudy.tistory.com
switch case의 예시 코드는 아래와 같다 #include #include int main() { int x = 0; switch (x) { case 1: // break; case 2: // [[fallthrough]] case 3: // break; default: // } } 위의 코드 내부는 아래와 같다 if (x
유닛테스트는 구현된 부분을 테스트하며 버그를 수정하여 로직의 완성도를 높이는 것이다 유닛테스트의 장점은 초기 단계에서 버그를 잡을 수 있고 샘플 코드의 역할을 한다 또한, 유지 보수를 쉽게 만들어준다 C++에서 Unit Test를 하기 위해서는 Google Test를 이용하는 방법이 있다 이는 빌드해서 바이너리를 실행해야 테스트가 가능하다는 복잡함이 있지만 Unit Test는 그만큼 중요하기 때문에 필수불가결하게 여겨지고 있다 간단한 예시는 아래와 같다 // GameLogic.h #pragma once class Enemy { public: float health; }; class Player { public: void Attack(Enemy& enemy, float damage); }; // GameL..
constructor에서 initializer list를 사용하면object를 더 효율적으로 생성할 수 있다 # 내부에서 선언 vs. initializer list내부에서 선언하는 코드는 아래와 같다class A{public: A() { m_b = B("param"); } private: B m_b;}; A의 멤버변수인 m_b가 만들어질 때, B의 constructor를 호출하며 object를 만들고A의 생성자 내부에서 "param"이 담겨있는 B의 constructor 통해 object를 만들고m_b에 copy를 한다이처럼 A의 멤버변수를 만들어내기 위해B의 오브젝트를 두 번 만들고copy도 한번 발생하니 효율이 좋지 않다 반면, initializer list를 이용하면class A{public: ..
random 한 데이터를 추출하기 위해서는 아래와 같은 방법을 자주 사용한다 #include int main() { srand(time(nullptr)); int radNum = rand() % 100; } 하지만, 이는 사실 균등한 랜덤이 아니다 예를 들어, 랜덤함수가 0부터 9까지 나오는 것이 기본이라는 가정을 한다면 이 함수를 가지고 0 ~ 3까지 나오게 하기 위해서 rand() % 4 를 하게 된다 실제로 0, 1, 2, 3의 비율이 균등하게 나오는 것이 아니라 랜덤함수를 열어보면 0, 1, 2, 3 을 통해 0, 1, 2, 3 4, 5, 6, 7 을 통해 0, 1, 2, 3 8, 9 에서는 0, 1 이처럼 균등하게 나오지 않고 0, 1의 비율이 높은 상태가 된다 따라서 모듈레이션을 통해 랜덤함수..