Przeciążenie operatora >>

0

Witam!

Usiłuję przeciążyć operator >> w ten sposób:

#include <QDebug>

class Worker
{
public:
    QString name; // debug

    void operator>>(Worker &o){
        qDebug() << this->name << o.name;
    }
};

int main()
{
    Worker w0, w1, w2;
    w0.name = "w0";
    w1.name = "w1";
    w2.name = "w2";

    w0 >> w1;
    //w0 >> w1 >> w2; // juz nie dziala
    return 0;
}

Niestety wiązanka z kilkoma ">>" już nie działa.
Chciałbym taką ładną metodą zsynchronizować pewne rzeczy w klasach, jak to zrobić?

1
    Worker &operator>>(Worker &o){
        qDebug() << this->name << o.name;
        return o; // lub return *this;
    }
0

A wiesz że na logikę też tak próbowałem? I wiesz co? Teraz działa ;) Dzięki.
Na forum wrzuciłem bez rodzica, a operator przeciążyłem w dzieciątku z typem rodzica :P

1

Kolejny, który zachwyca się przeładowywaniem operatorów :(.
Naprawdę nie jest ci to do szczęścia potrzebne, a biorąc pod uwagę kontekst użycia, to zdecydowanie nie powinieneś tego robić.

0

Dlaczego?

Może "synchronizacja" to złe słowo.

Mam kilka klas które pracują na wątkach i przetwarzają dane.
Klasy te mają wejścia i wyjścia danych oraz sterujących, które są zaimplementowane w rodzicu jako sygnały i sloty. Teraz chciałbym połączyć odpowiednie klasy:

// pisane z palca - chodzi o motyw
connect(w0, SIGNAL(dataChanged(QVector<int>)), w1, SLOT(setData(QVector<int>)), Qt::DirectConnection);
connect(w0, SIGNAL(rateChanged(int)), w1, SLOT(setRate(int)));
// ...

connect(w1, SIGNAL(dataChanged(QVector<int>)), w2, SLOT(setData(QVector<int>)), Qt::DirectConnection);
connect(w1, SIGNAL(rateChanged(int)), w2, SLOT(setRate(int)));
// ...

connect(w2, SIGNAL(dataChanged(QVector<int>)), w3, SLOT(setData(QVector<int>)), Qt::DirectConnection);
connect(w2, SIGNAL(rateChanged(int)), w3, SLOT(setRate(int)));
// ...

Oczywiście konfiguracji będzie dużo, czy nie lepiej zapisać to w ten sposób?:

w0 >> w1 >> w2 >> w3;

Jest czytelne a znaki >> idealnie pokazują przepływ danych.
Chciałbym jeszcze, aby podczas kolejnego wywołania np.

w0 >> w2 >> w3;

wywalić z połączeń klasę "w1" lecz jej nie niszczyć.

0

No to @MarekR22 ma całkowitą racje, na ile zrozumiałem co chcesz zrobić to weź stwórz osobną klasę konfigurującą.
Dla klasy Worker zrób setConfiguration(Configuration &c)
Jeżeli worker'y są sobie nie równe (co masz zupełnie mętnie wspomniane) to można zrobić: setSenderConfiguration(Configuration &c) oraz setReceiverConfiguration(Configuration &c)

1

Operatory są bardzo nieczytelne. Nie mówią co się dzieje. Z tego właśnie powodu należy ich używać TYLKO w ściśle określonych przypadkach:

  • dla obiektów, które są jednoznacznie kojarzone z jakąś arytmetyką (np macierze, liczby zespolone, kwateriony)
  • dla strumieni lub obiektów które zachowują się jak strumienie
  • mądre wskaźniki

W każdym innym wypadku, przeładowywanie operatorów jest mylące i wnerwiające każdego następnego programistę, który będzie utrzymywać dany kod.

Ty chcesz przeładowywać operatory dla wskaźników. To jest jeden z najgorszych przypadków zastosowania przeładowywania operatorów.
Dla każdego normalnego programisty, kto to zobaczy, pierwsza reakcja będzie WTF, a druga to wywalenie tego kodu.

0

Ale co złego jest w operatorach?
Początkowo pisałem wiązanki, później stworzyłem funkcję:

// nazwa wskazuje że było to tymczasowe bo mi się nie podoba
void MainWindow::tempConnect(const QObject * src, const QObject * dst){
    connect(src, SIGNAL(dataChanged(QVector<int>)), dst, SLOT(setData(QVector<int>)), Qt::DirectConnection);
    connect(src, SIGNAL(freqChanged(int)), dst, SLOT(setFreq(int)));
    connect(src, SIGNAL(rateChanged(int)), dst, SLOT(setRate(int)));
}
// ... //

Wykorzystanie:

    // oryginal
    tempConnect(generator, ui->spectrum);
  
    // mod
    tempConnect(generator, downsample);
    tempConnect(downsample, burst);

    tempConnect(burst, alignsample);
    tempConnect(alignsample, ui->spectrumBurst);

Wszystkie klasy dziedziczą po pewnej klasie, więc do tej klasy wrzuciłem pomocnika połączeń, a wykorzystanie tego wygląda tak:

  generator->connectTo(ui->spectrum);

  generator->connectTo(downsample);
  downsample->connectTo(burst);
  burst->connectTo(alignsample);
  alignsample->connectTo(ui->spectrumBurst);

I stało się jeszcze bardziej nieczytelne, więc postanowiłem wykorzystać operatory, aby zapis w kodzie był bardziej czytelny:

  generator >> ui->spectrum;

  generator >> downsample >> burst >> alignsample >> spectrumBurst;

?

0

Macie mocne argumenty :P

Aplikacja głównie będzie polegała na połączeniach, pojawi się też wizualizacja jak w JACK Audio gdzie łączy się wizualnie strumienie:
user image
Albo coś lepszego ^^

Póki co robię te połączenia w kodzie źródłowym i ciągle coś modyfikuję, mocno irytuje mnie wywoływanie funkcji do połączeń i zostanę na przeciążonym operatorze.
Operatory już zaimplementowane, naprawdę poprawiło to mocno czytelność kodu i już się tak nie gubię analizując co z czym jest połączone.
Spokojnie, dodam komentarz o co chodzi ;)

Jasne, jak znajdę lepszy sposób to zmienię, ale po kilku miesiącach rozwijania projektu, operatory wyglądają najlepiej.

0

Uwierz mi to nie poprawiło czytelności kodu, jedynie go skróciło. Nie chodzi o to, żeby było mniej literek, ale żeby od razu było wiadomo co się dzieje.
Wrócisz do tego kodu po 3 miesiącach przerwy, to wtedy zrozumiesz co mam na myśli.

1 użytkowników online, w tym zalogowanych: 0, gości: 1