목록언리얼 엔진/C++ (26)
게임 개발 메모장
묵시적이란? "직접적으로 말이나 행동으로 드러내지 않고 은연중에 뜻을 나타내 보이는. 또는 그런 것." 매개변수가 한 개인 생성자를 '변환 생성자(Conversion constructor)'라고 하는데 C++에서는 변환 생성자에서 묵시적으로 형변환이 일어나는 경우가 있다. #include using namespace std; class TestClass { public: TestClass(int param) : num(param) { cout
경쟁 상태 : 여러 스레드가 공유 리소스를 동시에 접근. : x86 프로세서에서 제공하는 INC는 아토믹하지 않으므로, 두 스레드의 작업이 겹치게 되면 예상치 못한 결과를 얻을 수 있다. 테어링 * 읽기 테어링 : 1번 스레드가 메모리에 데이터의 일부분만 쓰고 나머지 부분을 다 쓰지 못한 상태에서 2번 스레드가 이 데이터를 읽으면 두 개의 스레드가 보는 값이 달라진다. * 쓰기 테어링 : 두 스레드가 동일한 데이터의 다른 부분을 각각 쓰는 경우 각자 수행한 결과가 달라진다. 데드락(교착 상태) : 경쟁 상태를 막기 위해 상호 배제와 같은 기법을 사용할 때 발생하는 문제. 예시 : 1번 스레드는 A를 확보하고 B를 추가적으로 필요로 하는 동시에 2번 스레드는 B를 확보하고 A를 추가적으로 필요로 하는 상황..
이동 생성자란? 이름 없는 임시 객체가 생기는 것을 막을 수 없다. 그러나 무의미한 임시 객체의 생성은 프로그램의 효율을 떨어뜨린다. 이러한 문제 때문에 생긴 것이 이동 생성자이다. 임시 객체는 어차피 사라지는 객체이다. 깊은 복사를 수행할 필요 없이 얕은 복사를 수행함으로써 성능을 높일 수 있다. #include using namespace std; class TestClass { public: TestClass() { cout
복사 생성자(copy constructor)란? 복사 생성자란 객체의 복사본을 생성할 때 호출되는 생성자이다. 복사 생성자도 생성자와 마찬가지로 정의하지 않으면 컴파일러가 자동으로 만들어준다. 복사 생성자의 형태는 다음과 같다. 클래스이름(const 클래스이름 &변수이름); 다음 예제는 복사 생성자를 사용하였고 생성자와 마찬가지로 멤버 변수를 초기화하였다. #include using namespace std; class TestClass { public: TestClass(int param) : num(param)//생성자 초기화 { cout
main 안에서 실수로 값을 초기화 해버리는 문제가 생길 수 있는데, 이를 막을 수 있는 방법이 있을까? 정적 멤버 데이터(static member data) - static이 붙은 멤버 데이터 - 모든 객체가 공유한다. - 클래스 내부에 선언을 만들고 클래스 외부에 정의를 만들어야 한다. - 모든 객체가 공유한다. - 멤버 이므로 접근 지정자를 사용할 수 있다. class 내부에 static으로 변수를 선언한다. private로 선언하면 class 내부에서 getter/setter를 통해 해당 변수에 접근이 가능하게 만들 수 있다. class 내부에 static으로 선언된 cnt 값을 c1.getCount()로 호출해 가져올 수 있다. 출력 : 3 정적 멤버 데이터와 일반 멤버 데이터 아래 코드에서 -..
C++에선 런타임에 기초 클래스의 객체 포인터가 어떤 객체를 가리키고 있는지 정보를 알려주는 RTTI 기능을 제공한다. 객체지향에선 클래스 간 상속을 구현할 수 있고, 다형성을 가지게 되어 기초 클래스(Base class)는 자신의 멤버를 위임한 파생 클래스(Derived class)를 자신의 객체 포인터로 가리킬 수 있다. Base *pBase = new Derived(); 하지만 컴파일 당시에는 pBase가 어떤 객체를 가리키고 있는지 알 수 없다. 그저 가상 함수 테이블 vftable에 저장된 함수 주소가 무엇인지에 따라서만 기초 클래스와 파생 클래스 중 어떤 객체를 가리키고 있는지 짐작할 수만 있다. 하지만 그 자체가 정보로 주어지는 것도 아니기 때문에 프로그램은 실행 중에 포인터가 가리키고 있는..
복합 대입 연산자와 마찬가지로 복합 대입 연산도 가능하도록 할 수 있다. #include using namespace std; class TestClass { public: TestClass() {} ~TestClass() {} //변환 생성자 TestClass(int param) { num = new int; *num = param; } //형변환 허용 operator int() { return *num; } //복합 대입 연산자 TestClass& operator+=(const TestClass& ref) { //현재 값 int* newNum = new int(*num); //누적 값 *newNum += *ref.num; //기존 값 지우고 새 메모리 대체 delete num; num = newNum..
변수뿐만 아니라 클래스나 구조체에서도 단순 대입 연산이 이루어질 수 있다. #include using namespace std; class TestClass { public: TestClass() {} TestClass(int param) { num = new int; *num = param; } TestClass(const TestClass& ref) { num = new int; *num = *ref.num; } ~TestClass() { delete num; } int getNum() { return *num; } private: int *num = nullptr; }; int main() { TestClass a(10); TestClass b(20); a = b;//에러 cout
char 우선 char라는 변수 선언부터 언급해야 하는데 char은 문자라는 1-byte의 변수이다. 즉 단어 하나를 뜻하는 것이며 더 나아가 2-byte인 한글과는 문자 길이가 맞지 않아 깨진 것을 확인 할 수 있다. 또 char값에 정수를 대입해도 정수로 받아 들이는 것이 아닌 ASCII 코드로 해석한다. char a = 65; cout
C++ const, constexpr constexpr 이란 컴파일 시간 상수를 만드는 키워드 컴파일 시간에 결정되는 상수 값으로만 초기화 할 수 있다. constexpr이 변수를 상수로 만들어 준다고 하는데 그럼 const와 똑같은데 무슨 차이가 있나? 상수에는 2가지 상수가 존재하는데 1. 컴파일 시간에 알 수 있는 상수. 2. 컴파일 시간에 알 수 없는 상수. (실행시간에 알 수 있는 실행시간 상수) 이렇게 두 종류의 상수가 존재한다. 컴파일 시간에 알 수 있는 상수를 컴파일 시간 상수 (compile-time constant)라고 하고, 컴파일 시간에 알 수 없는 상수 즉 실행시간에 알 수 있는 상수를 런타임 상수(runtime constant)라고 한다. const는 컴파일 시간에 알 수 있는 ..