2013-02-21 4 views
0

저는 C++ 프로그래밍을 처음 접했고, 가상 멤버 함수를 포함하는 클래스의 크기에 대해서는 의문의 여지가 있습니다. 내 아래 코드를 따라 가십시오 :가상 멤버 함수를 포함하는 클래스의 크기

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

class BaseClass 
{ 
private: 
    int a, b; 
public: 
    BaseClass() 
    { 
     a = 10; 
     b = 20; 
    } 

    virtual int area() 
    { 
     return 0; 
    } 
}; 

class DerivedClass1 : public BaseClass 
{ 
    int x; 

public: 
    virtual void simple() 
    { 
     cout << "inside simple" << endl; 
    } 
}; 

int main() 
{ 
    DerivedClass1 Obj; 
    cout << sizeof(Obj) << endl; // Displays 16 bytes 

    return 0; 
} 

위의 코드는 크기를 16 바이트로 표시합니다. 나는 2 개의 가상 포인터 (하나는 기본 클래스에서 상속 받았고 하나는 가상 클래스의 자체 기능으로 인해 파생 클래스 자체에 추가됨) + 파생 클래스의 3 개 데이터 멤버가 20 바이트이기 때문에 20 바이트를 표시해야합니다. 그래서 설명해주세요 ....

+0

가상 포인터 상속 _and_ 다른 가상 포인터 추가? 왜 그런 일이 일어 났을까요? – jogojapan

+2

[가상 테이블] (http://en.wikipedia.org/wiki/Virtual_method_table)에 대한 설명 – borisbn

+1

다중 상속이있는 경우 추가 vptrs가 제공됩니다. 또한, 실험 결과는 컴파일러와 플랫폼에 따라 매우 다릅니다. [g ++로 컴파일 된] (http://liveworkspace.org/code/10xj5R$10)은 64 비트 실행 파일을 빌드 할 때 VS2012와 마찬가지로 24를 출력합니다. – Praetorian

답변

1

이 경우 가상 테이블 포인터는 클래스 계층 구조 전반에서 공통적으로 사용됩니다. 따라서 BaseClass에는 이미 가상 함수가 있습니다. DeriveClass1의 추가 가상 함수는 클래스 크기에 아무 것도 추가하지 않습니다.

class DerivedClass1 size(16): 
    +--- 
    | +--- (base class BaseClass) 
0 | | {vfptr} 
4 | | a 
8 | | b 
    | +--- 
12 | x 
    +--- 

Derivedass1::[email protected]: 
    | &DerivedClass1_meta 
    | 0 
0 | &BaseClass::area 
1 | &DerivedClass1::simple 

MVSC에서 컴파일 클래스의 메모리 레이아웃을 표시 할 때이 옵션을 -d1reportAllClassLayout 사용할 수 있습니다

는 클래스의 메모리 레이아웃입니다.

+0

파생 된 클래스 함수가 ​​더 커질 가능성은 없습니까? –

+0

BaseClass에 가상 함수가 없지만 DeriveClass에 하나 이상의 가상 함수가있는 경우. 이 경우 BaseClass (vfptr이 없음)와 비교하여 DerivedClass에서 vfptr (4bytes)가 더 많이 생깁니다. – HappyTran

관련 문제