:: ADVANCE ::
[C++] Class 본문
[C++] Class
<리스트 1 : Car class>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Car { private: int m_speed; int m_fuel; public: Car() { Speed(0); Fuel(0); } int Speed() { return m_speed; } void Speed(int speed) { m_speed = speed; } int Fuel() { return m_fuel; } void Fuel(int fuel) { m_fuel = fuel; } }; |
1 2 3 4 5 6 7 8 | Car car; 00401869 8D 4D F8 lea ecx,[car] 0040186C E8 8F F7 FF FF call Car::Car (401000h) car.Speed(0x12345678); car.Fuel(0x11111111); 0040187E 68 11 11 11 11 push 11111111h 00401883 8D 4D F8 lea ecx,[car] 00401886 E8 C5 F7 FF FF call Car::Fuel (401050h) | cs |
<리스트 1>에 간단한 Car 클래스가 나와 있다.
처음 C++이란 언어를 접하는 분들이 오해하는 가장 큰 이슈는 <리스트 2>에 나와 있다.
바로 Car와 car의 관계다. 오해하는 부분을 정리해보면 다음 두 가지로 요약된다.
1. 메모리에는 Car만 존재하고, 그것으로 인스턴스화 되는 것은 단지 참조할 뿐이다.
2. 메모리에는 Car의 모든 것이(멤버 변수, 멤버 함수) 인스턴스 별로 저장된다.
안타깝게도 두 가지 생각 모두 잘못된 상식이다. 실제로는 어떻게 처리되는지를 살펴보도록 하자.
<리스트 2>에 나타난 어셈블리 코드를 보면 알 수 있듯이 멤버 함수는 멤버 데이터와 완전히 별도로 처리된다.
즉 클래스의 인스턴스는 멤버 데이터만 저장할 수 있는 공간만 가지고 있다고 생각하면 된다.
멤버 함수는 같은 클래스에서는 똑같이 사용된다.
그렇다면 어떻게 다른 클래스인지를 자동적으로 알고 그곳에 저장할까? 그것은 멤버 함수 호출 규약에 있다.
C++ 컴파일러는 내부 적으로 멤버 함수를 호출할 때 그것의 인스턴스 정보를 함수에 같이 전달한다.
<리스트 2>에서는 ecx에 그 정보를 담고 있다.
각 멤버 함수는 넘어온 해당 인스턴스 정보를 this를 통해 참조해서 인스턴스에 맞는 정보를 처리할 수 있는 것이다. 실제로 이렇게 호출이 일어난 후의 인스턴스 메 모리 공간을 살펴보면 <화면 1>과 같이 8바이트의 데이터 공간만 존재한다는 것을 볼 수 있다.
좀 더 정확하게 표현하자면 클래스의 인스턴스에는 멤버 데이터를 위한 공간과 C++ 컴파일러가 클래스를 다루는데 필요한 메타데이터가 저장된다. Car 클래스의 경우 이러한 메타데이터가 전혀 없기 때문에 멤버 데이터만 저장된 것이다.
따라서 메타 데이터가 손상될 수 있기 때문에 클래스로 만든 데이터는
절대로 원시 데이터 타입(primitive data type)처럼 취급해서는 안 된다.
이러한 대표적인 실수가 클래스를 메모리에서 직접 복사하거나(memcpy) 파일에 직접 기록하는(fwrite) 것 이다.
'language > C | C++' 카테고리의 다른 글
[C] auto, static, extern 키워드 의미 (0) | 2015.12.16 |
---|---|
[C/C++] C++ 기능 3 (0) | 2014.09.16 |
[C/C++] C++ 기능 2 (0) | 2014.09.16 |
[C/C++] C++ 기능 1 (0) | 2014.09.16 |
[C/C++] C와 C++ (0) | 2014.09.16 |