2010-01-17 8 views
3

전역 연산자 new/delete/new []/delete []가 오버로드되었지만 새 버전과 새 버전이 올바르게 호출되는 동안 간단한 배열 할당과 새 [] 및 삭제 [ ]를 호출하면 newaop.cpp 및 delete2.cpp의 구현이 호출됩니다. 예를 들어연산자 new와 연산자 new [] 사이의 차이점은 무엇입니까?

,이 코드

int* a = new int[10]; 

전화 연산자 새 [] 차례로 new 연산자의 내 버전을 호출 newaop.cpp,있다. 그래서 그들은 전세계에 과부하가 걸려 있지만 어떤 이유로 배열 버전이 아닌 것 같습니다. 내가 빠진 것이 있습니까?

편집 : 연산자의 구현은 별도의 프로젝트에 있으며 라이브러리로 컴파일되어 정적으로 연결됩니다. 되돌아 보면 원래 게시물에 포함하는 것이 유용했을 수도 있습니다. 아마도이 작업과 관련이 있기 때문입니다. 배열 버전 만 영향을받는 이유는 아직 모르지만.

+0

무엇이'newaop.cpp'와'delete2.cpp'입니까? –

+0

모든 것이 예상대로 작동하는 것 같습니다.'new int [10]'는 함수를 호출합니다. 완전한 테스트 케이스를 제공하고 실제 동작이 예상 한 것과 어떻게 다른지 설명 할 수 있습니까? –

+0

과부하의 프로토 타입을 게시하십시오. – Potatoswatter

답변

0

좋아, 나는 이것을 관리하여 누군가 다른 사람이 우연히 발견했을 때 게시하고있다.

연산자가 호출되지 않은 이유는 구현이 연산자에 호출 된 프로젝트가 아니라 라이브러리에 있기 때문입니다. 사실 기술적으로 연산자의 구현을 포함하기 만하면되므로 이미 전역 적으로 정의되어 있으므로 내 라이브러리의 .cpp 연산자 만 구현하도록 지정했습니다 (잘못된 단계였습니다). 코드에는 라이브러리의 헤더 파일 만 포함되어 있었으며 구현에 대한 가시성은 없었습니다. 또한 Visual Studio는 newaop.cpp와 delete2.cpp를 내 응용 프로그램에 연결 한 것 같습니다. 이 두 파일에는 operator new [] 및 operator delete [] (일반 new/delete가 아닌 bot) 구현이 포함되어 있습니다. 이것이 컴파일러가이 두 가지 구현을보고 라이브러리의 .cpp 파일에있는 광산에서 선택한 이유 일 가능성이 큽니다.

이 솔루션은 내 오버로드 된 연산자의 구현을 내 코드에서 직접 포함 된 라이브러리의 헤더 파일로 옮기는 것입니다.

+1

이 질문은 원래 질문에 넣거나 페이지의 맨 아래에 있기 때문에 가능한 경우 대답을 선택하지 않아야합니다. - 오버로드의 구현을 헤더에 넣지 않아도됩니다.표준에서는 기본 버전을 "프로그램"의 구현으로 대체해야하며 정적 라이브러리가 포함되어야합니다. – Potatoswatter

+0

예, 라이브러리는 포함되어 있습니다. 문제는 Visual Studio에서 newaop.cpp와 delete2.cpp를 링크 한 것인데,이 연산자는 해당 연산자에 대한 구현을 포함하고 컴파일러는이를 광산에서 선택했습니다. 이후 그것은 연산자의 배열 버전에만 영향을 미쳤습니다! 정규 운영자는 정확히 동일한 방식으로 정의되고 작동합니다. –

0

operator new는 하나의 객체를 할당하고 생성자를 호출합니다. new []는 n 개의 객체를 할당하고 n 개의 생성자를 호출합니다.

편집 : 여러 개의 새로운 [] 및 삭제 [] 오버로드가 약간 이상한 것으로 간주 될 수 있습니다. 컴파일러는 어떤 것을 링크 할지를 어떻게 알 수 있습니까? 과부하를 게시 할 수있는 기회가 있습니까? 또한 newaop과 delete2를 연결하지 않으면 호출됩니다 (즉, exe에서 유일한 구현입니다)?

+0

내 질문에 관한 차이점을 언급하고있었습니다. 내가 충분히 명확하지 않은 경우에 미안. –

+1

Goz : 특정 기능 ("대체 기능")을 바꿀 수 있습니다 (18.4.1 참조). –

+0

임 잘 알고 있습니다 ...하지만 두 번 교체하는 것은 이상하게 보입니다 ... newaop 및 delete2가 CRT 파일이 아니라면 ...하지만 일부 코드는 여전히 유용 할 것입니다 ... – Goz

3

난 당신이 operator new[] 과부하하지만 난 그냥 MSVC2008와 그것을 시도 방법을 모른다 :

void* operator new[](size_t size) 
{ 
    return 0; 
} 

int main() 
{ 
    int* a = new int[5]; 
} 

위의 코드는 효과적으로 operator new[]의 내 결함 구현을 호출합니다.

이유는 무엇입니까? operator new[] 오버로드에 실패했으며 프로그램에 에 의존하는 operator new[]의 컴파일러 버전이 사용됩니다. operator new을 오버로드 했으므로 구현이 호출됩니다.

+0

결함 대체가 연산자 new []에 대한 요구 사항을 위반하고 정의되지 않은 동작을 호출하기 때문에 어떤 일이 발생할 수 있습니다! : P –

+1

내 목적은 null 포인터를 반환하는'operator new []'에 디버그 단계를 수행하는 것입니다. 내 예제에서는 여기에 총알이없는 구현을 붙여 넣기를 원하지 않았으므로 분명히 버그가있는 것으로 작성하고 멀리 걸릴 수는 없다. :) –

+0

그래서 내가 혀를 말해 주었다. : P 언제든지 UB를 호출하는 것은 좋지 않지만 위의 예제를 사용하여'new int [5]()'를 시도하는 것과 같은 중요한 문제를 숨길 수 있습니다. 실제로 새로운 []을 구현할 수 없다는 점을 지적 할 가치가 있다고 생각했습니다. 이 C++. –

0

코드가 버그이지만 어떤 것도 게시하지 않았다고합니다. 내 생각 엔 size_t이 아니라 과부하의 인수로 int을 사용했을 것입니다. 일부 과부하는 컴파일러가 해당 인스턴스에서 관대하기로 결정했기 때문에 호출 될 수 있습니다.