2010-12-29 2 views
1

다음과 같이 가정 해 보겠습니다. 클래스에 fwrite()를 사용하면 어떻게됩니까?

class dataClass { 
public: 
    int someData; 
    float moreData; 
    void setData(); 
}; 
dataClass data;
fwrite(&data, sizeof(data), 1, outputFilePointer);을 호출하면 어떻게됩니까? 코드가 마치 dataClass에 기능이없는 것처럼 동작합니까, 아니면 각 구성원에게 fwrite()을 호출해야합니까?

+1

왜 보지 않습니까? :) – fingerprint211b

+1

b/c 표준에 의해 허용되는 것이 있으면 휴대용 컴퓨터에서 시도 할 수 있습니까? –

+2

이 방법은 이식 가능하지만 작성된 내용이 플랫폼간에 일치하지 않아야합니다. –

답변

3

이 경우에는 클래스가 POD이므로 일반 Old C 구조체와 똑같이 작동합니다. 즉, data의 메모리 표현을 덤프합니다 (컴파일러가 패딩 바이트 포함). 삽입 할 수 있음). virtual 방법, virtual 상속 등 C++의 물건에서 개막하는 경우

그러나, 당신은 이상한 물건 (당신이에 넣어 일반 데이터 필드뿐만 아니라 vtable에 대한 포인터 그리고 아마도 다른 것들뿐만 아니라 볼 수가 표시 될 수 있습니다 컴파일러에 의해 자동으로); 나는 또한 다중 상속이 혼란을 더할 수 있다고 생각한다.

그러나 개체에 fwrite을 호출하면 모든 경우에 해를 끼치 지 않습니다 (별다른 동작 일지 모르지만 확인하지는 않았 음). 대신 fread과 함께 파일에서 비 POD 객체를 비 직렬화하려는 경우 문제가 발생할 수 있습니다 (예 : 파일에 저장된 올바른 vtable 포인터가 더 이상 유효하지 않을 수 있으므로이 경우 올바른 다음 가상 전화에서 모든 것을 날려 버리십시오.)

+0

"_it이 (가) 지정되지 않았을 수 있습니다."_ 거의 모든 경우에 출력되는 데이터가 지정되지 않았습니다. – curiousguy

4

클래스가 POD 유형이고 귀하의 유형이 맞으면 제대로 작동합니다.

+0

포인터는 POD입니다. –

+0

C++ 11 : http://www.cplusplus.com/reference/type_traits/is_pod/ – Will

0

당신이 동적으로 할당하지 않는 한 회원, 간단한 구조의 좋아 (주의를 : 단지 동일한 플랫폼, 즉 엔디안과 64 분의 32에) 작동합니다 (효과적으로은 무엇인가) memcpy이 이후

+0

동적 할당은 클래스가 POD (또는 C++ 0x, "표준 레이아웃")인지 여부와 전혀 관련이 없습니다. . –

+0

@Ben, 내가 회원님의 의견을 듣고 있는지, 내가 회원이 아닌 클래스 자체에 대해 이야기하고 있는지 확실하지 않습니다. – Nim

+0

상관 없어요. 'memcpy' 포인터는 완벽하게 합법적입니다. 반면에 기본 생성자, 가상 함수, 다중 상속, 혼합 된 액세스 지정자 또는 하위 객체의 비 PODness는 모두 'memcpy'정의되지 않은 동작을 사용합니다. –

0

POD 클래스이므로 바이트를 버킷으로 처리하는 것이 좋습니다.

1

C++에서 모든 객체는 일련의 바이트로 표시되며 모든 유형의 객체는 바이트 배열로 재 해석 될 수 있습니다. 이것은 정확히 fwrite이라고 할 때 일어납니다. 객체에 대한 포인터를 지정하고 객체의 크기가 얼마나되는지를 알려주고 객체를 해당 바이트의 배열로 재 해석합니다.

유형이 POD인지 여부는 중요하지 않습니다. non-POD 타입의 객체는 바이트 배열로도 재 해석 될 수 있습니다. 비 POD 유형의 객체를 바이트 배열로 재 해석하는 것에 대한 정의가 없습니다. (결과는 대부분 POD가 아닌 유형에 대해 구현에 따라 정의되지만, 다른 문제입니다.)

POD가 아닌 유형의 객체에 대한 문제점은 기본 저장 영역의 사본을 예를 들어, fwrite을 사용하거나 메모리의 다른 위치로 복사하는 경우) 사본으로 할 수있는 일이 많지 않습니다. fread 복사본을 메모리에 다시 저장할 수없고 원래 개체 인 것처럼 사용할 수 있으며 원래 개체 유형의 개체 인 것처럼 바이트 복사본을 다시 해석 할 수 없습니다.

클래스가 POD 클래스 인 경우에도 포인터 유형의 데이터 멤버가있는 클래스에서 비슷한 문제가 발생합니다. 포인터가 가리키는 객체가 아닌 포인터의 값만 복사했기 때문에 ' 실제로 필요한 모든 데이터를 복사했습니다. 파일에서 복사 된 데이터를 의미있는 방법으로 읽을 수는 없습니다. 실제 오브젝트를 참조하지 않는 포인터로 끝나기 때문입니다. 실제로는 의도하지 않습니다.

다른 사람들은 자기가 포함 된 POD 유형의 객체를 가지고 있어도 이런 식으로 파일을 이식 할 수는 없으며 다른 플랫폼에서 올바르게 읽을 수 있기를 기대할 수 있습니다. 기본 유형의 크기와 표현의 차이, 데이터 구조 패딩 (padding)과 정렬 (alignment)과 같은 구현 정의의 다른 것들.

관련 문제