2011-03-23 7 views
6

QObject로 인해 여러 상속과 관련하여 QT에 문제가 있습니다. 나는 많은 다른 사람들이 같은 문제가 있다는 것을 알고 있지만 나는 그것을 어떻게 고쳐야하는지 모른다.Qt 다중 상속 및 신호

class NavigatableItem : public QObject 
{ 
    Q_OBJECT 

    signals: 
     void deselected(); 
     void selected(); 
     void activated(); 
}; 

class Button : public NavigatableItem, public QToolButton 
{ 
    Q_OBJECT 

    ... 
} 

class MainMenuOption : public Button 
{ 
    Q_OBJECT 

    ... 
} 

나는이

MainMenuOption* messages = new MainMenuOption(); 
connect(messages, SIGNAL(selected()), SLOT(onMenuOptionSelected())) 

내가 오류를 얻을 것이다 수행 할 때 : 나는 때문에 신호의 QObject를에서 NavigatableItem의 enherit을 할 이유

QObject' is an ambiguous base of 'MainMenuOption'

이유를. 이것을 할 수있는 방법이 있습니까?

편집 : 각 상속 선언에 가상 추가

, 여전히 나에게 같은 오류를 제공합니다 :

class NavigatableItem : public virtual QObject 

class Button : public virtual NavigatableItem, public virtual QToolButton 

class MainMenuOption : public virtual Button 

심지어 '깨끗한 모든', '실행 qmake를'과 '구축 모든'후 .

+5

가 여러 QObject를 상속 할 수 없습니다 서브 클래스. 이 중 하나만 QObject가 될 수 있으며 목록의 첫 번째 것이어야합니다. –

+1

'moc_ *','* .obj' 파일을 삭제하고 모두 다시 빌드 해보세요. – liaK

+0

업데이트 된 질문보기. 재건축으로 문제가 해결되지 않았습니다. – RvdK

답변

8

,하지만 내가 과거에했던 것은 순수한 그들 중 하나 (이 경우에 NavigatableItem)를 만드는 것입니다 가상 클래스, 즉 인터페이스. "signals"매크로를 사용하는 대신 순수 가상 보호 기능을 사용하십시오. 그런 다음 QObject 파생 클래스뿐만 아니라 인터페이스를 다중 상속 받고 메소드를 구현하십시오.

다소 논란의 여지가 있지만 다중 구현 상속을 피하는 것은 많은 문제와 혼란을 해결합니다. Google C++ Style Guidelines은 이것을 권장하며 좋은 조언이라고 생각합니다.

class NavigatableItemInterface 
{ 
    // Don't forget the virtual destructor! 
    protected: 
     virtual void deselected() = 0; 
     virtual void selected() = 0; 
     virtual void activated() = 0; 
}; 

class Button : public NavigatableItemInterface, public QToolButton 
{ 
    Q_OBJECT 
    ... 
    signals: 
     virtual void deselected(); 
     ... 
} 
+0

감사합니다. Dave, 이것은 제가 한동안 수행 한 작업이므로 최소한 프로젝트를 구축 할 수있었습니다. 그러나 한 가지 부작용은 NavigatableItem이되어야하는 textentry 객체가있는 경우 각 선택 해제/선택 및 활성화 된 신호를 재정의해야한다는 것입니다. – RvdK

+2

다시 정의해야하지만 다시 구현할 필요는 없습니다. 일반적으로 이러한 클래스를 공용 클래스 (아마도 유틸리티 클래스)에 넣고 상속 클래스의 private 멤버로 포함하고 상속 클래스에 'has-a'관계가 있어야합니다. -관계. 예, 약간의 추가 코드이지만 실제 비즈니스 로직을 한 곳에서 관리하여 "복사하여 붙여 넣기"오류를 방지 할 수 있습니다. 나는 다중 상속에 대한 다른 문제를 피하는 것이 가치가 있다는 것을 알았지 만, 나는 단지 그것을 단지 의견으로 인정한다. –

1

가상 상속을 사용하십시오.

class X : public virtual Y 
{ 
}; 

class Z : public virtual Y 
{ 
}; 

class A : public virtual X, public virtual Z 
{ 
}; 

에만 기본 클래스의 사본이있을 것이다 Y

그것은 조금 더 많은 코드를 필요로
+0

모든 상속 선언에 virtual을 추가했지만 여전히 동일한 오류가 발생했습니다. – RvdK

+1

다음을 실행하여 MOC 파일 재생성을 시도하십시오. make distclean; qmake; 하다. – Tobias

+0

업데이트 된 질문보기 가상 및 리빌딩을 추가해도 문제가 해결되지 않았습니다. – RvdK