Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [c++] sovraccaricare operatore <= per liste

    Salve a tutti,
    ho un bel dubbio di implementazione (più che altro sintattico perchè non sono molto pratico con il sovraccarico di operatori).

    Se ho l1 che è una lista e voglio confrontare un elemento in una specifica posizione con un'altra posizione, del tipo voglio vedere che:

    l1.leggilista(3) <= l1.finelista()

    Ovvero ho un elemento della lista e voglio controllare che si trovi prima di una determinata posizione, nell'esempio prima della fine della lista.

    Come posso sovraccaricare l'operatore? ovvero, come parametro gli passo una posizione, ovvero l1.finelista, ma poi all'interno dell'operatore (che definirò dentro l'oggetto lista) come posso riferirmi sia all'intero oggetto l1 (quindi che ne so alla testa della lista) che alla posizione 3?

    Cioè ho un sovraccarico dell'operatore <= di questo genere:

    codice:
    bool operator<=(posizione b) {
    [..]
    }
    Supponiamo che nel main richiamo l'espressione l1.leggilista(3) <= 3, dove leggilista(3) è un elemento, c'è modo di referenziarsi sia a questa posizione 3 che all'oggetto lista l1? Come si può tradurre sintatticamente?

    O se sto facendo un errore di logica, come si potrebbe sviluppare assieme? Se l1.leggilista(3) fosse una posizione della lista l1, posso referenziarmi comuqnue alla lista l1 tipo con un this-> all'interno dell'operatore sovraccaricato?

    Ok ammetto di essere un pò a digiuno, sto scartabellando un pò sul manuale, qualsiasi esempio pratico/teorico è il benvenuto.

    Vi ringrazio in anticipo,
    Neptune.
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  2. #2
    La domanda è un po' disordinata, comunque cerco di risponderti come meglio posso.

    L'overloading degli operatori binari (=che accettano due argomenti, uno a sinistra e uno a destra) si può effettuare o con una funzione libera o con una funzione membro.

    Il primo caso è il più semplice: si crea una funzione sciolta con nome operator seguito dal simbolo dell'operatore, ad esempio operator>=; i parametri ricevuti saranno due, e saranno dei riferimenti (const quando è il caso) ai due tipi in questione. Il tipo "naturale" restituito naturalmente varia a seconda dell'operatore, ma il linea di massima se non ricordo male è possibile restituire qualunque tipo.

    L'overloading di un operatore di confronto potrà essere espresso ad esempio con:
    codice:
    bool operator<=(const posizione & Left, const posizione & Right)
    {
        // ...
    }
    Nota che i riferimenti qui sono costanti perché non ha senso che un operatore di confronto modifichi i suoi operandi, e soprattutto deve poter essere chiamato anche su oggetti const (in sola lettura). Tra l'altro se non erro nulla vieta di avere tipi diversi per Left e Right; i nomi sono arbitrari, semplicemente ti ricordano che il primo parametro è quello che nell'espressione sta a sinistra del <= e il secondo sta alla sua destra.

    (parentesi: tieni conto che in generale quando c'è bisogno di implementare un operatore di confronto, la stragrande maggioranza degli algoritmi STL richiede che ci sia il < e l'==, di rado vengono richiesti gli operatori compositi o il > - fine parentesi)

    L'altro metodo invece prevede la definizione dell'operatore all'interno della classe del tipo che sta alla sinistra. In tal caso sarà una cosa del genere:
    codice:
    bool operator<=(const posizione & Right) const
    {
    
    }
    L'operando di sinistra è la classe su cui è invocato il metodo, ossia this. Nota che qui è this ad essere const (l'oggetto su cui opera il metodo non è modificabile) dato che la funzione è dichiarata come tale.

    Per ulteriori informazioni sulle definizioni "standard" degli operatori in overloading, ti consiglio di dare un'occhiata a questa pagina.

    Aggiungo anche questo come linee guida "logiche" (e non semplicemente sintattiche) su come effettuare l'overloading.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Quindi se dichiaro un operatore all'interno di una classe si intende come "sottointeso" che l'operatore a sinistra sia l'oggetto di cui l'operatore fa parte?

    Quindi se dichiaro il mio <= nella classe "liste_collegate" e gli passo una posizione avrò a disposizione l'intera lista e la posizione passate.

    Se invece lo faccio esterno alla classe posso decidere io i due operandi, ma nel caso gli facessi entrambi di tipo "posizione" poi non avrei modo di riferirmi in nessun modo all'oggetto lista, giusto?

    Ma quindi come potrei fare a risolvere il mio problema?
    Se ho due posizioni in una lista non sequenziale (metti che è una con puntatori e quindi le posizioni sono indirizzi di memoria e quindi non matematicamente confrontabili) come faccio a stabilire se l'indirizzo A è minore dell'indirizzo B, è maggiore o magari non appartiene prorpio alla lista? hai qualche consiglio a riguardo perchè a questo punto mi sono un pò perso

    (Il codice su cui lavoro è sempre il solito liste_collegate come superclasse, con le tre classi che ereditano e sviluppano liste con cursore, liste con puntatore e liste con vettore, con i vari metodi leggilista, scrivilista, insinlista, primolista, finelista..)
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  4. #4
    L'unico modo che mi viene in mente a questo punto è quello di svilupparlo come un metodo normale in cui gli passo due posizioni, e non come il sovraccarico di un operatore.
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  5. #5
    Originariamente inviato da Neptune
    L'unico modo che mi viene in mente a questo punto è quello di svilupparlo come un metodo normale in cui gli passo due posizioni, e non come il sovraccarico di un operatore.
    Se lo puoi fare come metodo che confronta due posizioni lo puoi fare come operatore in overloading su due posizioni; peraltro nulla ti impedisce di creare l'operatore in questione solo per i tipi-posizione con cui ti è comodo fare questo lavoro.
    Se hai una lista a puntatori per confrontare due elementi dovrai percorrere la lista cercando l'altro elemento. Questa è un'operazione piuttosto costosa, e non a caso la STL per le liste fornisce iteratori non confrontabili per distanza, ma solo per uguaglianza/differenza; se proprio serve sapere chi viene prima, viene fornito l'algoritmo distance (che opera su qualunque tipo di iteratore) che fornisce la distanza tra due iteratori.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Originariamente inviato da MItaly
    Se lo puoi fare come metodo che confronta due posizioni lo puoi fare come operatore in overloading su due posizioni; peraltro nulla ti impedisce di creare l'operatore in questione solo per i tipi-posizione con cui ti è comodo fare questo lavoro.
    Se hai una lista a puntatori per confrontare due elementi dovrai percorrere la lista cercando l'altro elemento. Questa è un'operazione piuttosto costosa, e non a caso la STL per le liste fornisce iteratori non confrontabili per distanza, ma solo per uguaglianza/differenza; se proprio serve sapere chi viene prima, viene fornito l'algoritmo distance (che opera su qualunque tipo di iteratore) che fornisce la distanza tra due iteratori.
    Non riescoa capire come fare il sovraccarico degli operatri. Se io all'operatore passo due posizioni (che potrebbe essere l'indice di un array come un indirizzo di memoria) poi l'operatore come fa a capire di che lista stiamo parlando? Cioè se io passo un indice 3 per la lista co array sequeziale o con cursore che è sempre collegata ma viene salvata su un array statico, il mio operatore comefa a sapere che ti stai riferendo a lista1 di tipo lista?

    Se lo sviluppo come metodo di lista sarà sottointeso che l'operando destro sia una lista ed il secondo lo imposto io di tipo posizione, ma a me in realtà seriverebbe la lista più due posizioni da confontare tra loro nella lista, come se fosse un operatore ternario o comunque un metodo che lavora su tre parametri. Come dovrei svilupparlo?
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  7. #7
    Per essere più chiari, se volessi trasformare questo metodo in sovraccarico dell'operatore <= ?

    Da notare che sostanzialmente mi serve potermi ricavare la testa della lista mediante il metodo primoLista() e poter controllare che la lista non sia finita mediante il metodo finelista(posizione) che mi restituisce un booleano.

    Se io creo una un sovraccarico di operatore dentro liste_collegate poi si aspetterà che un operatore sia proprio un oggetto di tipo liste_collegate e l'altro a mio piacere quindi di tipo posizione. Ma come faccio a passargli la seconda posizione?

    Se invece la dichiaro come funzione sciolta posso passargli due posizioni, ma come gli passo la lista su cui operare?

    codice:
    template< class T, class P >
    bool liste_collegate<T,P>::controllo_posizione(posizione p1, posizione p2) const
    {
         posizione testa;
        
         bool val_return = false;
         
         testa =  primoLista();
         
        //scandisce finchè non arrivo a p2 o comunque non arrivo a finelista
       //supponiamo però che almeno p2 è una posizione valida
         while( (testa != p2) && !finelista(testa) && (val_return == false) )
         {
             if(testa == p1)
                 val_return=true; 
               
             testa=succlista(testa);     
         }
        //caso in cui la posizione p1 è proprio il finelista  e/o è proprio p2
        if(testa == p1)
            val_return=true; 
    
        return val_return;        
    }
    "Estremamente originale e fantasioso" By darkiko;
    "allora sfiga crepuscolare mi sa che e' meglio di atmosfera serale" By NyXo;
    "per favore, già è difficile con lui" By fcaldera;
    "se lo apri te e invece di "amore" ci metti "lavoro", l'effetto è lo stesso" By fred84

  8. #8
    Potresti o memorizzare dentro a posizione un puntatore alla lista madre (indispensabile se gli elementi sono memorizzati rispetto ad un buffer allocato nella classe mdare), oppure scorrere la lista di puntatori (a partire dall'elemento di sinistra) in avanti e indietro, se si trova l'elemento restituisci il valore adeguato, altrimenti sollevi un'eccezione; o ancora, puoi fregartene e lasciare il caso come "undefined behavior": scorri la lista di puntatori in un solo verso, se trovi l'elemento di destra allora restituisci true (è >=), se non lo trovi restituisci false, documentando che il comportamento degli operatori di confronto sulle posizioni non è definito se si cercano di confrontare posizioni di due liste differenti.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.