C/C++
- Hash Table 원리 및 개념 공부
- 표준 'String' 클래스
- 짧은 문자열에 대해서는 동적으로 메모리를 할당하지 않고 그냥 지역 변수로 보관
- 문자열을 복사할 때 복사된 문자열의 내용이 바뀌지 않는 한 실제 데이터를 복사하는 것이 아니라 원래 문자열을 가리키기만 함.
=> 속도를 향상시키기 위한 여러 노력이 접목되어 있음.
- 상속
- 상속받은 파생 클래스에서 기반 클래스의 생성자를 명시적으로 호출하지 않을 시 기반 클래스의 디폴트 생성자가 호출된다.
=> 기반 클래스의 생성자를 호출할 땐 파생 클래스의 초기화 리스트에서 호출해주어야 원하는대로 동작한다.
=> 파생 클래스의 초기화 리스트가 아니라 생성자 내부에서 기반 클래스의 생성자를 호출하면, 디폴트 생성자가 1회, 사용자가 호출한 생성자가 1회 각각 호출된다.
- 'is-a' 관계이다.
ex) 사람과 프로그래머 사이의 관계를 생각해보자. "프로그래머는 사람이다."는 참이지만 "사람은 프로그래머이다"는 거짓이다.
=> 클래스가 파생되면 파생될 수록 좀 더 특수화(구체화, specialize) 된다.
=> 반대로, 기반 클래스로 거슬러 올라갈 수록 좀 더 일반화(generalize) 된다.
- 모든 클래스들의 관계를 'is-a'로만 표현할 수는 없다. 어떤 클래스들 사이에서는 'has-a' 관계가 성립되기도 한다.
ex) 자동차 - 엔진, 브레이크 등
=> 'has-a' 관계에서는 클래스의 멤버변수로 다른 클래스를 갖는다
- 파생 클래스에서 기반 클래스로 캐스팅 하는 것을 업 캐스팅이라고 부른다.
- 기반 클래스에서 파생 클래스로 캐스팅 하는 것을 다운 캐스팅이라고 부른다.
=> 오류가 발생할 가능성이 높음
=> 컴파일러 상에서 함부로 다운 캐스팅 하는 것을 금지하는 경우도 있음.
=> 강제적으로(ex : static_cast<파생 클래스>(변수명)) 다운캐스팅 하는 경우, 컴파일 타임에서 오류를 찾아내기 매우 힘들기 때문에 다운 캐스팅은 작동이 보장되지 않는 한 권장되지 않는다.
- 캐스팅 오류를 미연에 방지하기 위해 C++에서 상속 관계에 있는 두 포인터들 간에 캐스팅을 해주는 dynamic_cast 라는 것을 지원한다.
=> 사용법은 static_cast와 거의 동일하다.
=> 다운캐스팅시에 기반 클래스에 가상함수가 없을 경우 dynamic_cast를 사용해도 컴파일 에러가 발생한다.
=> 기반 클래스에 가상함수가 있다면, dynamic_cast를 사용하면 컴파일 에러를 내지 않고 대신 nullptr값을 리턴한다.
=> 레퍼런스 타입으로 캐스팅하려 할 경우 base_cast를 throw 하게 된다(?)
- 컴파일 시에 어떤 함수가 실행될 지 정해지지 않고 런타임 시에 정해지는 일을 가리켜서 동적 바인딩(dynamic binding)이라고 부른다. ↔ 정적 바인딩(static binding) : 컴파일 타임에 어떤 함수가 호출될 지 정해진다.
- virtual 키워드가 붙은 함수를 가상 함수(virtual function)라고 부른다.
=> 파생 클래스의 함수가 기반 클래스의 함수를 오버라이드 하기 위해서는 두 함수의 꼴이 정확히 같아야 한다.
- C++ 11 에서는 파생 클래스에서 기반 클래스의 가상 함수를 오버라이드 하는 경우, override 키워드를 통해서 명시적으로 나타낼 수 있다.
=> override 키워드를 사용하게 되면, 실수로 오버라이드를 하지 않는 경우를 막을 수 있다.
=> 이전에 가상함수를 사용할 경우 파생클래스에서도 함수 앞에 virtual을 붙여서 가상함수임을 명시하는것이 좋다고 배웠었는데, virtual을 붙이는 것보다 override 키워드를 붙여주는 것이 더 좋겠다.
- 상속될 여지가 있는 Base 클래스들은 반드시 소멸자를 virtual로 만들어주어야 나중에 문제가 발생할 여지가 없다.
- 기반 클래스에서 파생 클래스 함수에 접근할 때 기반 클래스의 포인터를 통한 접근 뿐만 아니라 기반 클래스의 레퍼런스여도 문제 없이 동작한다.
- 하나의 메소드를 호출했음에도 불구하고 여러가지 다른 작업들을 하는 것을 다형성(polymorphism)이라 한다.
- 가상 함수의 구현 원리
- 가상함수를 사용하게 되면 약간의 오버헤드(overhead)가 존재한다.
=> 모든 함수들을 virtual로 만들어선 안되는 이유.
=> 실제로 자바의 경우 모든 함수들이 디폴트로 virtual 함수로 선언된다.
- C++ 컴파일러는 가상함수가 하나라도 존재하는 클래스에 대해서 가상 함수 테이블(virtual function table; vtable)을 만들게 된다.
=> 가상 함수 테이블은 전화 번호부라고 생각하면 편하다.
=> 함수의 이름(전화번호부의 가게명)과 실제로 어떤 함수(그 가게의 전화번호)가 대응되는지 테이블로 저장하고 있는 것
- 비 가상함수들은 특별한 단계를 걸치지 않고, 해당 함수를 호출하면 직접 실행된다.
- 가상함수들은 호출했을 때, 가상 함수 테이블을 걸쳐서 실제로 어떤 함수를 고를지 결정하게 된다.
=> 이와 같이 두 단계를 걸쳐서 함수를 호출함을 통해 소프트웨어적으로 동적 바인딩을 구현할 수 있게 된다.
=> 가상함수를 호출하는 경우, 일반적인 함수보다 약간 더 시간이 걸리게 된다.
=> 차이는 극히 미미하지만 최적화가 매우 중요한 분야에서는 이를 감안할 필요가 있기 때문에 다른 언어들과 다르게 C++에서는 멤버 함수가 디폴트로 가상함수가 되도록 설정하지 않는다.
- 순수 가상함수와 추상 클래스
- 함수의 몸통이 정의되어 있지 않고 단순히 =0; 으로 처리되어 있는 가상함수를 완전한 가상함수라는 의미로 순수 가상 함수라고 한다.
=> 무엇을 하는지 정의되어 있지 않는 함수로 반드시 오버라이딩 되어야만 하는 함수다.
- 순수 가상 함수는 본체가 없기 때문에 해당 함수를 호출하는 것 자체가 불가능하다. 따라서 순수 가상 함수를 가지는 클래스 객체를 생성하는 것도한 불가능하다.
=> 순수 가상 함수를 최소 한 개 이상 포함하고 있는 클래스는 객체를 생성할 수 없으며, 인스턴스화 시키기 위해서는 해당 클래스를 상속 받는 클래스를 만들어서 모든 순수 가상 함수를 오버라이딩 해주어야 한다.
- 순수 가상 함수를 최소 1개이상 포함하고 있는 반드시 상속 되어야 하는 클래스를 가리켜 추상 클래스(abstract class)라고 부른다.
- 추상 클래스를 '설계도'라고 생각하면 좋다.
=> 해당 클래스를 상속받아서 사용하는 사람에게 "이 기능은 일반적인 상황에서 만들기 힘드니 직접 특수화 되는 클래스에 맞추어서 만들어 써라"라는 의미로 전해진다.
- 다중 상속(multiple inheritance)
- C++에서는 한 클래스가 다른 여러 개의 클래스들을 상속 받는 것을 허용한다.
=> 이를 가리켜서 다중 상속이라 부른다.
- 다중 상속은 보통의 상속과 똑같이 생각해도 무방하다.
=> 생성자 호출 순서는 상속하는 순서에만 좌우된다.
- 다중 상속시, 기반 클래스에 같은 이름의 변수 혹은 함수가 있다면 어떤 것을 호출하는 것인지 알 수 없어 오류가 발생할 수 있다.
- 다이아몬드 상속(diamond inheritance)
=> 각각의 기반 클래스에서 변수명이나 함수명을 안 겹치게 만들더라도 결국 최상위 기반 클래스를 상속받으니 최하위 파생 클래스에서는 모든 내용이 중복되는 문제가 발생한다.
=> 최상위 기반 클래스를 virtual로 상속받으면 다중 상속 시에도, 컴파일러가 언제나 최상위 기반 클래스를 한 번만 포함하도록 지정할 수 있게 된다.
- 브릿지 패턴(bridge pattern), 중첩된 일반화 방식(nested generalization), 다중 상속
=> 위 3가지 방식 중 절대적으로 우월한 방식은 없고 상황에 맞게 최선의 방식을 골라서 써야한다.
DirectX 11
- 8장 텍스처 적용
- 포스팅 링크 : [DirectX11] 텍스처 적용 (tistory.com)
- 8장 텍스처 예제
- 포스팅 링크 : [DirectX11] 텍스처 예제 (tistory.com)
Directx11을 하는 동안 C++에 대해 공부했던 내용을 까먹지 않기 위해 C++ 이론 및 알고리즘 공부를 병행해야겠다.
C++에 대한 내용은 씹어먹는 C++ 강좌를 보고 작성한 내용입니다.
'TIL' 카테고리의 다른 글
[TIL] 20230104 성장일지 (0) | 2023.01.05 |
---|---|
[TIL] 20221130 - 20221202 성장일지 (0) | 2022.12.02 |
[TIL] 20221123 - 20221125 성장일지 (0) | 2022.11.25 |
[TIL] 20221122 성장일지 (0) | 2022.11.23 |
[TIL] 20221121 성장일지 (0) | 2022.11.22 |
댓글