2013-12-11 3 views
0

이미지 데이터 (픽셀 및 헤더)를로드 및 저장 (삭제)하는 클래스가 있습니다.소멸자에서 delete []를 호출하고 클래스 객체를 매개 변수로 함수에 전달합니다.

IMAGE_DATA::IMAGE_DATA():data(0) 
{ 
    memset(&fileheader,0,(sizeof(BITMAPFILEHEADER))); 
    memset(&infoheader,0,(sizeof(BITMAPINFOHEADER))); 
}; 

및 데이터로드 함수 new[...]에 할당 된 unsigned char* 배열 : 생성자에서 I는 다음과 같이 데이터 비트 맵 헤더를 초기화한다. 소멸자 :

IMAGE_DATA image; 

image.load("filename"); //load headers and pixel data 

FILTER filter; 

filter.scale(image,scalefactor,"outputfilename"); //scales the image and write to a .bmp 

이 내 코드의 단축 버전입니다 :

IMAGE_DATA::~IMAGE_DATA() 
{ 
    freeData(); 
}; 

void IMAGE_DATA::freeData() 
{ 
    delete[] data; 

    memset (&fileheader, 0, sizeof(fileheader)); 
    memset (&infoheader, 0, sizeof(infoheader)); 
}; 

이제 문제는 필터링 클래스에서, 내가 클래스 객체 후 매개 변수로 데이터를로드 통과한다는 것입니다. 코드가 스케일링 기능에 도착할 때 그래서, IMAGE_DATA ::load 실행 부드러운, 그러나, 나는 다음과 같은 어설 션 오류 얻을 :

Debug Assertion Failed! 
.... 
Expression: 
_BLOCK_TYPE_IS_VALID(pHeap->nBlockUse) 
.... 

CRT 의를 \ SRC \ dbgdel.cpp라인에서 52

이것은 소멸자를 만들었 기 때문에 발생합니다. 호기심 때문에 나는 매개자를 바꾸어 기준으로 삼았습니다.

/*FILTER::*/scale(IMAGE_DATA& /*passed as reference*/, unsigned short, const char*); 

그리고 이제 작동합니다. 'value by'를 전달하면 소멸자가 호출 된 것처럼 보이지만 생성자에서도 마찬가지입니다. 생성자에서 모든 것을 초기화하므로 아무런 문제가 없어야합니다.

원본을 변경하지 않고 그대로두고 싶기 때문에 값으로 전달하고 싶습니다. 단지 데이터를 사용하고 싶습니다.

값으로 전달하는 것과는 다른 방식으로 참조로 전달하지 않고 어떻게 작동시킬 수 있습니까? 값으로 볼 때 '안전함'이 더 높습니다.

편집 : 난 그냥 이것에 대해 게시물을 발견했습니다 : Side effects when passing objects to function in C++ (나는 보인다 적절한 키워드로 검색 적이 없다) 그래서 내가 복사 생성자를해야 읽은이 게시물 및 과제에서 운영자.

답변

1

C++에는 'threes'규칙이 있습니다. 기본적으로, 사용자 정의 소멸자가있는 경우 복사 생성자와 복사 할당 연산자를 작성해야합니다.

'값으로 전달'할 때 생성자가 호출된다고 가정 할 수 있습니다. 그러나 제공 한 기본 생성자가 아니라 복사 생성자입니다.

컴파일러가 정의하지 않으면 컴파일러에서 제공하는 모든 포인터의 '얕은'복사본을 만듭니다. 기본적으로 복사본은 원본과 동일한 메모리를 가리 킵니다. . 나는 당신이 왜 당신의 원본을 삭제하는지 이해할 수 있다고 생각한다. :)

+0

hm 나는 이것에 관한 한 개의 게시물을 발견했다 : D와 나는 팁 +1에 감사한다. 나는 이것을 7 분 안에 받아 들일 것입니다. –

+1

그리고 C++ 11에서, "rule of three"는 "rule of five"로 확장되었습니다 - rvalue references의 소개와 함께, 'move constructor'과 당신이 구현해야만하는'move assignment operator '. 이는 일반적으로 멤버를 원시 포인터로 선언하지 말고 스마트 래퍼를 사용하여 복사/이동/파괴 의미를 처리하도록합니다. –

관련 문제