C++ Primer 1 ~ 5장 후기
2026. 4. 9. 02:09ㆍ카테고리 없음
우선 C++ Primer 1~5장은 기본적인 내용이었다
그래서 그냥 읽어 보고 기초 지식을 점검해보았다 그리고 직접 실습을 해보았다
기본적인 개념들은 그냥 읽어보고 실습은 총3가지를 해보았다
#include <iostream>
using namespace std;
int main() {
char c_arr[3] = {'A', 'B', 'C'};
int i_arr[3] = {10, 20, 30};
double d_arr[3] = {1.1, 2.2, 3.3};
cout << "char step : " << (long long)(c_arr + 1) - (long long)c_arr << " byte" << endl;
cout << "int step : " << (long long)(i_arr + 1) - (long long)i_arr << " bytes" << endl;
cout << "double step: " << (long long)(d_arr + 1) - (long long)d_arr << " bytes" << endl;
return 0;
}

이렇게 배열은 타입마다 메모리를 건너뛰어 메모리에 할당하는것을 보았다



그리고 각 Cast들에 대해 조금 확인을 해보았다
1. static_cast
컴파일 타임에 변환 (가장 기본)
특징
- 타입 간 명시적 변환
- 컴파일러가 안전하다고 판단하면 허용
int main() {
double d = 3.14;
int i = static_cast<int>(d);
std::cout << "double d의 주소: " << &d << " | 값: " << d << std::endl;
std::cout << "int i의 주소 : " << &i << " | 값: " << i << std::endl;
return 0;
}



-> "static_cast<int>(double)를 실행하면 CPU 레벨에서 cvttsd2si 명령어가 실행되는 것을 확인했다. 이는 단순히 메모리를 다르게 보는 것이 아니라, 실제로 소수점을 잘라내고 정수 비트로 재구성하는 물리적인 변환 과정이 일어난다는 것을 의미한다."
2. dynamic_cast
런타임 타입 체크 (RTTI 기반)
특징
- 상속 관계에서만 사용 가능
- 반드시 virtual 함수가 있는 클래스 필요
- 실패 시:
- 포인터 → nullptr
- 참조 → 예외 발생
#include <iostream>
class Base {
public:
virtual void hello() { std::cout << "Base\n"; }
};
class Derived : public Base {
public:
void hello() override { std::cout << "Derived\n"; }
};
int main() {
Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b);
if (d) d->hello();
delete b;
return 0;
}


어셈블리에서 __RTDynamicCast 이것을 호출한다
내부 동작
- 객체 내부의 vtable → RTTI 정보 확인
- 실제 객체 타입을 검사해서 맞으면 변환
여기서 Dynamic Cast는 Static과 다르게 변환이 실패하면 nullptr 혹은 std::bad_cast 예외를 발생하여서 안정성에서 훨씬 좋다 (Static은 쓰레기 주소를 줘버림)
3. const_cast
const제거
특징
- const 속성만 변경
사용 예
const int a = 10;
int* p = const_cast<int*>(&a);
*p = 20;
내부 동작
- 단순히 상수성만 제거
- 실제 메모리 보호는 없음
4. reinterpret_cast
비트 단위 재해석 (가장 위험)
특징
- 완전히 다른 타입으로 해석
- 컴파일러는 거의 검사 안 함
사용 예
#include <iostream>
int main() {
int n = 0x41424344;
char* p = reinterpret_cast<char*>(&n);
std::cout << "--- reinterpret_cast 실습 ---" << std::endl;
std::cout << "int n의 주소: " << &n << std::endl;
std::cout << "ptr p의 주소: " << (void*)p << std::endl;
std::cout << "p가 가리키는 첫 번째 칸의 문자: " << *p << std::endl;
std::cout << "p가 가리키는 두 번째 칸의 문자: " << *(p + 1) << std::endl;
return 0;
}



내부 동작
- 비트 그대로 유지
- 타입만 바꿔서 해석