2011-01-13 3 views
2

가능한 중복 : 예
How are objects stored in memory in C++?C++에서 클래스의 메모리가 어떻게 처리됩니까?

은 C++ 클래스 :

class A{ 
int value; 
void addOne(){ 
    value++; 
} 
}

클래스 A의 인스턴스는이 [의사 코드]과 같이 로딩 될 것이다 :

 
[identifier of A] 
[this is int value] 
[this is void addOne(void)][value++] 
또는 다음과 같이하십시오 :
 
[members identifier of A] 
[this is int value]

[functions identifier of A] [this is void addOne(ref to member of A)][A.value++]

둘째로 적은 메모리를 사용해야합니다. 한 클래스의 여러 인스턴스에서. 동일한 함수가 모든 인스턴스에 사용되기 때문입니다. C++에서 메모리를 어떻게 처리합니까? 메모리 처리를 변경할 수 있습니까?

+0

"A의 식별자"란 무엇입니까? 또는 "A의 회원 식별자"? –

+0

죄송합니다. 적절한 복제본이 아닙니다. – GWW

+0

이 질문에 대한 답변이 있습니까? http://stackoverflow.com/questions/2006504/c-data-alignment-member-order-inheritance/2007980#2007980 – Beanz

답변

3

멤버 함수가 클래스 인스턴스에 저장되어 있는지 묻는 중입니까? 각 인스턴스는 동일한 함수를 사용하며 [인스턴스의] 주소는 숨겨진 매개 변수 this으로 전달됩니다.

+0

거의 그렇지 않습니다. 또한 typeid()를 호출하지 않는 한 클래스 식별자가 어디에서도 발견되지 않는다는 메모를 추가합니다. – Puppy

+0

네, 제 질문이었습니다. 나는이 같은 것을 손으로해야한다고 생각했다. 고맙습니다. – schwer

1

질문이 클래스 A의 메모리 레이아웃에 관한 것이라면 struct A 즉 정수 값을 갖는 것과 같습니다. 4 바이트 (또는 해당 플랫폼의 int에 대한 바이트)
기능은 이 아니며 메모리 레이아웃의 일부입니다. 함수 나 유사한 것으로 저장된 포인터로, 클래스의 크기에는 영향을주지 않습니다.
클래스 A가 다형성 클래스 인 경우 크기는 vtable에 대한 포인터를 포함하기 때문에 다를 수 있습니다.

1

배치는 더 같이 실제로 :

클래스 인스턴스 : 다른

[this is int value] 

어딘가에 :

입니다
[this is void addOne(ref to member of A)][A.value++] 

는, 클래스가 (정확히)의 멤버 변수로 구성되어 있으며 그것의 기본 클래스, 더 이상 (귀하의 클래스가 가상 함수를 포함하지 않는 한, 가상 함수 테이블도 포함) - 특히 "식별자"가 없습니다.

다른 클래스의 인스턴스와는 완전히 다른 곳에 저장되는 함수와 동일합니다. 게다가, 클래스의 함수는 그 클래스에 대한 참조 나 그 멤버에 대한 참조를 포함하지 않는다. 이것은 단지 메모리 블록의 코드 (machine code statements) 일뿐입니다. 함수를 호출 할 때 클래스 인스턴스에 대한 포인터를 호출 스택에 푸시 한 후 해당 위치로 점프합니다 (기본적으로). 그런 다음 메서드는 스택의 포인터에 액세스하여 인스턴스 (및 멤버)에 액세스 할 수 있습니다.

+0

빈 줄과 함께 이것을 의미했습니다. 더 명확하게 기록해야합니다. – schwer

0

글쎄요, Randall 'Hyde 's Great Code Volume 2 (위대한 책, 자유 시간이 있다면 읽으십시오)에 그 부분 만 말해줍니다. 간단히 말해서, 클래스가 바로 structs 같은 변수를 보유하고 있지만, 해당 클래스에 선언 된 함수에 대한 포인터를 유지하는 레코드 (VMT)이 있습니다

VMT는 가상 메서드 테이블의 약자를 이러한 4 바이트에 대한 포인터를 포함 클래스의 "메소드 포인터"배열. 가상 메서드 ( C++의 가상 멤버 함수라고도 함)는 특수 클래스 관련 함수이며 클래스의 필드로 선언합니다.
[...]
가상 멤버 함수를 호출하면 두 개의 간접 액세스가 필요합니다. 먼저 프로그램은 클래스 개체에서 VMT 포인터를 가져와 을 사용하여 VMT에서 특정 가상 함수 주소를 간접적으로 가져와야합니다. 그런 다음 프로그램은 VMT에서 가져온 포인터 을 통해 가상 구성원 의 기능을 간접적으로 호출해야합니다.
[...]
주어진 클래스에는 메모리에 VMT 복사본이 하나만 있습니다. 지정된의 모든 객체가 동일한 VMT를 공유하므로이 객체는 정적 객체입니다.

+1

이것은 완전히 정확하지 않습니다. 첫째, C++에서 메모리 레이아웃면에서 클래스와 구조체 간의 차이는 없습니다. 두 번째로 질문에있는 예제에는 vtable/VMT가 없으므로이 설명은 오도 된 것입니다. –

+0

@Konrad : 방금 그 책에서 복사했습니다. = P – BlackBear

관련 문제