2013-09-01 5 views
1

현재 공개 QWidgets 인 3 개의 클래스가 있습니다. -> x, y, z는 모두 q 위젯입니다.Qt : Q 위젯 및 포인터

내 메인 윈도우에는 x, y, z에 대한 포인터가 있습니다. > 무효 전환의 원인 -이 deleteScreen(&m_x); :

그래서 회원 :

X* m_x; 
Y* m_y; 
Z* m_z; 

멤버 함수는 :로

void MainWindow::deleteScreen(QWidget** widget) 
{ 
    if(widget != NULL) 
    { 
     delete widget; 
     widget = NULL; 
    } 
} 

했다.

deleteScreen 매개 변수를 QWidget* widget으로 변경하고 deleteScreen(m_x)으로 호출하면 메모리가 삭제되지만 m_x은 NULL로 설정되지 않습니다. (로컬 변수, 위젯 만)

->deleteScreen 함수가 주어진 위젯을 삭제하고 멤버 변수의 값을 NULL에 두는 방법이 있습니까?

감사합니다.

+1

경우 * 위젯을 삭제할 수 :

는 코드에 대한 대안으로 다음을 시도 * widget = NULL;}' –

+1

QWidgets을 삭제해야합니까? AFAIK, Qt는 일종의 가비지 수집을 구현합니다. –

+0

@AlexFarber Qt가 가비지 콜렉션을 가지고 있다는 것을 몰랐습니다. 하지만 솔루션이 어떻게 작동하지 않을까요? 나는 그런 것을 시도했지만 deleteScreen (& m_x) -> invalid conversion 함수를 호출 할 수 없다. – secondVISION

답변

2

실제로, a double pointer to a base class cannot be used as a double pointer to a derived class;

template<typename T> 
void deleteAndCleanup(T*& ptr) 
{ 
    delete ptr; 
    ptr = NULL; 
} 

// called like this: 
deleteAndCleanup(m_x); 
+0

참조를 취하는 버전에서 NULL을 확인할 필요가 없습니다. NULL 포인터에 대한 delete 호출은 완벽합니다. (역 참조를하기 때문에 포인터를 취하는 버전에서 여전히 NULL을 확인해야합니다.) –

+0

@NikosC .: NULL 검사는 필요하지 않습니다. 이중 포인터가 NULL이면 호출자에 심각한 논리 결함이 있으므로 segfault는 많은 가치가 있습니다. –

+0

이봐, 첫 번째 솔루션을 시도했지만 잘못된 변환을 제공합니다. 오류 : 'X **'에서 'QWidget **'[-fpermissive] – secondVISION

3

여기서 문제는 당신이 QWidgets 삭제를 너무 많이하지 않습니다하지만 당신은 그들에게 포인터를 사용하고 있다는 것은이 삭제되었는지의 여부를 확인하기 : 그래서 당신은 아마 템플릿에 의존해야합니다.

Qt는 이에 대한 해결책이 있습니다. QObject 클래스의 경우 QPointer 클래스를 가드로 사용할 수 있습니다. 객체에 포함 된 QObject이 객체의 삭제에 내부적으로 연결되어 삭제되었는지 여부를 알고 있습니다. `{(! = null의 위젯 = 널 & & * 위젯)

QPointer<X> m_x; 
QPointer<Y> m_y; 
QPointer<Z> m_z; 


template<typename T> 
void MainWindow::deleteScreen(QPointer<T> &widget) 
{ 
    if(!widget.isNull() && qobject_cast<QWidget>(widget) != 0) 
    { 
     widget->deleteLater(); 
    } 
} 
+0

'&& qobject_cast (widget)! = 0' 부분이 실제로는별로 유용하지 않다고 생각합니다. 그것을 유지하고 싶다면'&& widget-> parent() == this' 또는 뭔가를 추가하여 실제로 어떤 종류의 안전 검사로 작동하게해야합니다. – hyde

+0

내가 체크인을 한 이유는 secondVISION의 원래 코드와 비슷한 기능을 만들기 위해서 였기 때문에'QWidget' 항목 만 함수에 의해 처리되어야합니다. 'QPointer'는'QObject'뿐만 아니라'QWidget's도 가질 수 있기 때문에이 제한은 템플릿 함수로 만들어지게됩니다. – RobbieE