2012-09-09 2 views
0

IF 문 내에 객체를 선언하려는 다음 코드가 있습니다. IF로 선언하는 것만으로도 나머지 프로그램의 범위를 벗어난다는 것을 이해합니다. 그래서 포인터를 사용해야한다고 생각합니다. 제 문제는 사용자가 선택할 수있는 클래스가 기본 클래스에서 파생된다는 것입니다. 그래서이 기본 클래스를 기반으로 포인터를 만들 필요가 있다고 생각했습니다. 맞나요?외부에서 사용하기 위해 IF에서 파생 클래스를 선언하는 경우

내가 뭘하려고하는지 아래에서 보시라. 나는 올바른 볼 파크에 있습니까?

//create a stereo input object 
StereoImage SO; 
SO.open(File1,File2); 

int StereoOption; 

if (counter == 0) StereoOption = 1; 

//think i need to create a pointer to the base class 
SVAlgorithm *ptrSter; 

//choose which method to use in stereo processing and set the base class pointer to derrived class 
    if (StereoOption == 1) {SVOpenCVBlockMatching DoStereo; cout << "Using option 1" << endl; *ptrSter = DoStereo;} 
else if (StereoOption == 2) {SVOpenCVSemiGlobalBlockMatching DoStereo; cout << "Using option 2" << endl; *ptrSter = DoStereo;} 
else if (StereoOption == 3) {SVNoMD DoStereo; cout << "Using option 3" << endl; *ptrSter = DoStereo;} 
else if (StereoOption == 4) {SVCross DoStereo; cout << "Using option 4" << endl; *ptrSter = DoStereo;} 
else if (StereoOption == 5) {SVAdaptDP DoStereo; cout << "Using option 5" << endl; *ptrSter = DoStereo;} 

//set create DoStereo from the pointer 
SVAlgorithm &DoStereo = *ptrSter; 

//output matrix 
Mat_<short> DispOut; 

//load the disparity method params, compute it and show - works 
DoStereo.loadParams(); 
DoStereo.compute(SO.getRawFrame(0),SO.getRawFrame(1),DispOut); 
imshow("Disparity Map", DispOut*255); 

다음 클래스는 모든 클래스 SVAlgorithm에서 파생 된 ... SVOpenCVBlockMatching, SVOpenCVSemiGlobalBlockMatching, SVNoMD, SVCross, SVAdaptDP.

SVAlgorithm *ptrSter = SVFactory(StereoOption); 

여기서 당신이 올바른 방향으로 시작

+0

, 당신이해야하지 그것을 역 참조 그래서. 스마트 포인터로 바꾸고'if' 내에 메모리를 할당하는 것을 권하고 싶습니다. – chris

+0

무엇이 질문입니까? – Walter

답변

1

아니요, 코드가 잘못되었습니다. 포인터는 객체 수명에 절대적으로 아무런 영향을 미치지 않습니다. 따라서이 라인 SVAlgorithm &DoStereo = *ptrSter;은 파괴 된 개체에 대한 포인터를 역 참조하려고하기 때문에 정의되지 않은 동작을 제공합니다.

다른 가능한 문제는 ptrSterStereoOption 변수가 초기화되지 않았습니다. 여기에 보이는 것은 ptrSter이 적절한 객체로 지정되지 않고 해당 참조가 UB로 이어질 가능성이있는 경우입니다.

new 문과 동적 저장 장치를 사용해야 포인터가 결과에 저장됩니다. 스마트 포인터을 원시 대신이 용도로 사용하는 것이 좋습니다. C++ 03의 경우 std::auto_ptr 또는 C++ 11의 경우 std::unique_ptr입니다.

예 :

귀하의 포인터가 초기화되지 않았습니다
std::unique_ptr<SVAlgorithm> ptrSter; 

if (StereoOption == 1) { ptrSter.reset(new SVOpenCVBlockMatching()); } 
else if (StereoOption == 2) { ptrSter.reset(new SVOpenCVSemiGlobalBlockMatching()); } 
else if (StereoOption == 3) { ptrSter.reset(new SVNoMD()); } 
else if (StereoOption == 4) { ptrSter.reset(new SVCross()); } 
else if (StereoOption == 5) { ptrSter.reset(new SVAdaptDP()); } 

if(!ptrSter) 
{ 
    assert(false); 
    return; 
} 

SVAlgorithm &DoStereo = *ptrSter; 
+0

여러분, 고맙습니다. – Oliver9523

1

: 당신이 그런 짓을해야하므로

SVAlgorithm *ptrSter; 

는하지만 지금은 당신이 당신의 인스턴스 중 하나를 만드는 공장 같은 것을 필요 SVFactory()은 if 문을 다음과 같이 캡슐화합니다.

SVAlgorithm* SVFactory(int StereoOption){ 
    if (StereoOption == 1) { return new SVOpenCVBlockMatching(); } 
    else if (StereoOption == 2) { return new SVOpenCVSemiGlobalBlockMatching();} 
    else if (StereoOption == 3) { return new SVNoMD();} 
    else if (StereoOption == 4) { return new SVCross();} 
    else if (StereoOption == 5) { return new SVAdaptDP();} 
} 

이상 :

delete ptrSter; 
+1

2012 년에 원시 포인터를 사용하는 것은 좋지 않습니다. 1992 년에도 좋지 않았지만, 지금은 누군가가 탈 필요가있을 때 말을 사는 것이 좋습니다. – Rost

관련 문제