:: ADVANCE ::

[C++] Class 본문

language/C | C++

[C++] Class

KSJ14 2015. 7. 13. 00:05
반응형

[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; }
};



<리스트 2 : 클래스 생성 및 멤버 함수 호출 과정>
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) 것 이다.


[참고] http://jiniya.net/lecture/maso/cpp.pdf

반응형

'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
Comments