Wieloznaczność podczas dziedziczenia

0

Mam taki problem, moja klasa dziedziczy 2 klasy z biblioteki Qt.

class MyWindow: public QWidget, public QThread{...};

Obie te klasy dziedziczą tę samą klase QObject.
Jeżeli chce uzyć funkcji dostepnej wlasnie z QObject to niestety kompilator wywala błąd. Nie mam pojecia jak sobie z tym poradzić, bo przeciez nie mogę redefiniować klas z biblioteki Qt.

Jakieś sugestie?

3

Po co Ci takie monstrum? Nie lepiej odziedziczyć normalnie QWidget i zawrzeć wewnątrz tej klasy obiekt typu QThread? Możesz spróbować dziedziczenia wirtualnego, ale nie wydaje mi się, że to pomoże.

Edit:
Źle się wyraziłem. Ten obiekt wewnątrz to Twój wątek czyli obiekt klasy dziedziczącej po QThread.

0

Z tego co kiedyś czytałem, po QThread nie należy dziedziczyć.

0

Faktycznie moge tak zrobic tak jak napisałes :) Dzieki za odpowiedz.
Jednak myslalem ze są jakies narzędzia ktore pozwolą mi to ładnie odziedziczyc.

0

QWidget::QObject::metoda(...) lub QThread::QObject::metoda(...)

1

Przedmówcy mają oczywiście raję, nie brnij w tę stronę.
Natomiast jak się odwołać do danej bazy kiedy dziedziczymy wielokrotnie? A tak:

struct CommonBase { void Foo(); };
struct BaseOne : CommonBase { };
struct BaseTwo : CommonBase { };

struct Derived : BaseOne, BaseTwo {
    void Bar()
    {
        this->BaseOne::Foo(); // lub BaseOne::Foo();
        this->BaseTwo::Foo(); // lub BaseTwo::Foo();
    }
};

//edit
@krwq mnie uprzedził

0

W sumie to najlepiej jakbys tylko po QWidget podziedziczyl a QThread bylo polem klasy

0

Napisaem tak :

 QWidget::QObject::connect(back,SIGNAL(clicked()),this,SLOT(cofnij()));
      QWidget::QObject::connect(NewGameButton,SIGNAL(clicked()),this,SLOT(newGame())); 

Wywaliło :
błąd:'QObject' is an ambiguous base of 'MyWindow'... To moze jednak błąd mam po prostu gdzie indziej.

0

Ale tak czy inaczej, to co mi radzicie, a dokładniej to co napisał Endrju Działa, wiec dzieki za odpowiedzi. Pozdro

1

Edytowałem pierwszy post bo nie wyraziłem się dokładnie. Żeby w Qt użyć wątków, należy napisać klasę, która dziedziczy po QThread i zaimplementować metodę run(). Musisz więc napisać dwie klasy: tę Twoją dziedziczącą po QWidget oraz klasę wątku, której obiekt będzie w tej pierwszej. Ta klasa wątku może być wewnątrz pierwszej, jeżeli nigdzie indziej nie będzie ona używana.

0
Azarien napisał(a):

Z tego co kiedyś czytałem, po QThread nie należy dziedziczyć.

@Endrju - @Azarien dobrze napisał. Też tak kojarzyłem i wszedłem w dokumentację on-line. http://qt-project.org/doc/qt-4.8/QThread.html - na samym dole znajdują się notatki. Andre dodał notkę o tytule Subclassing no longer recommended way of using QThread, tak więc jest inna zalecana metoda do pracy z wątkami.

0
Hostel napisał(a):

@Endrju - @Azarien dobrze napisał. Też tak kojarzyłem i wszedłem w dokumentację on-line. http://qt-project.org/doc/qt-4.8/QThread.html - na samym dole znajdują się notatki. Andre dodał notkę o tytule Subclassing no longer recommended way of using QThread, tak więc jest inna zalecana metoda do pracy z wątkami.

A kto te rekomendacje ustala? Ta notka jest od jakiegoś pana, który stosuje QThread inaczej. Nie podał żadnych przeciwwskazań, czy jakiegokolwiek argumentu, że jego sposób jest lepszy. Ten ktoś to nie jest dev Qt (to pod avatarem oznacza, że ma certyfikat w używaniu Qt) - to taki sam komentarz jakich masa jest pod manualem php. W oficjalnej dokumentacji jest wciąż co innego.

0

http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ - wpis na blogu Qt Labs. Facet tłumaczy że powinno się nie dziedziczyć po QThread. Jeśli coś jest niezalecane to po co z uporem maniaka to coś stosować? Najprawdopodobniej gdy wyjdzie Qt 5 to wtedy trzeba będzie wyrzucać dziedziczenie po QThread, ponieważ zostanie poprawiona architektura.

0
see_you_in_hell napisał(a):

Napisaem tak :

 QWidget::QObject::connect(back,SIGNAL(clicked()),this,SLOT(cofnij()));
      QWidget::QObject::connect(NewGameButton,SIGNAL(clicked()),this,SLOT(newGame())); 

Wywaliło :
błąd:'QObject' is an ambiguous base of 'MyWindow'... To moze jednak błąd mam po prostu gdzie indziej.
Dlaczego z uporem czepiłeś się złego rozwiązania jakim jest dziedziczenie wielokrotne? Nie rób tego, każdy Ci to radzi. Podam rozwiązanie tylko dlatego, że mnie korci nierozwiązany problem. Ale nie rób tego :D .

/* tu warto podać jawnie "this->" bo inaczej wygląda to jakbyśmy wołali składnik statyczny */
this->QWidget::connect(back,SIGNAL(clicked()),this,SLOT(cofnij()));
this->QWidget::connect(NewGameButton,SIGNAL(clicked()),this,SLOT(newGame())); 
1

#Nie WOLNO dziedziczyć po QObject wielokrotnie! Mało tego jeśli jest dziedziczenie wielokrotne, to klasa rozszerzająca QObject MUSI być pierwsza na liście! patrz dokumentacja QObject
#NIE należy dziedziczyć po QThread. Wszystkie instrukcje mówiące inaczej, są wynikiem dziedzictwa historycznego Qt (artykuł autora klasy QThread). Prawidłowe podejście to własny QObject i przenieś go do innego wątku moveToThread i pozwolić domyślnej pętli przetwarzania komunikatów z QThread przetwarzać sygnały docierające do slotów.

0

Dla niedowiarków, co uważają że nadal powinno się dziedziczyć po QThread zgłoszony bug związany z DOKUMENTACJĄ:
https://bugreports.qt-project.org/browse/QTBUG-23635

0

Wow, cytujecie wciąż jedno i to samo źródło.

Tylko, że w tym oto źródle jest napisane tak:

Bradley T. Hughes June 21, 2010 at 9:59 am (...)

To set the record straight: I’m not saying sub-classing QThread is wrong. This is also how Java does it (sort of), and many people have been doing this with Qt for a long time.

What I’m saying is “wrong” is subclassing QThread, adding signal and slot code to that subclass, and then calling moveToThread(this); in the constructor of that subclass.

Już rozumiecie, co jest złe i o czym był ten wpis na blogu? (Pisałem to już wcześniej w komentarzu)

Zacytuje jeszcze raz słowa rzekomego autora QThread: "I’m not saying sub-classing QThread is wrong".

Czy ktoś z Was w ogóle potrafi określić co jest złego w samym dziedziczeniu po QThread?

A propos dokumentacji, z tego samego komentarza autora:

I’m planning on sitting down and fleshing them out, showing both ways of using QThread (with and without subclassing).

0

Czemu nie dziedziczyć po QThread:
#mechanizm sygnałów i slotów lepiej działa gdy się tego nie robi. Dziedziczenie po QThread powoduje, że pojawiają się dodatkowe problemy z wielowątkowością podczas przetwarzania slotów. moveToThread na obiekcie dziedziczącym po QThread, zamiast naprawić sytuacje jeszcze ją pogorszy, przykładowo slot deleteLater w tej sytuacji doprowadzi do zawieszenia się wątku.
#testowanie. Testowanie nowej funkcjonalność wplecionej w QThread jest koszmarem. Natomiast w przypadku osobnej klasy jest to dziecinnie proste.

Dlatego właśnie napisałem "NIE należy dziedziczyć po QThread". Jeśli się już to robi to trzeba uważać na dodatkowe pułapki, których nie będzie jeśli zrezygnuje się z dziedziczenia.

0

Może uściślijmy. Klasę QThread można rozszerzać, jest na to przygotowana. Ale implementacja jakiegoś konkretnego zadania które ma wykonywać się w wątku nie powinna opierać się o dziedziczenie po QThread z różnych względów (było już tu kilka przytoczonych). QThread ma stworzyć środowisko uruchomieniowe dla algorytmu, ale nie "być" algorytmem. Co innego jeśli chcieli byśmy rozszerzyć to środowisko o jakieś dodatkowe ficzery związane z wykonywaniem wątków, wtedy dziedziczenie po QThread jest jak najbardziej wskazane.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.