Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2011
    Messaggi
    7

    Restituire un oggetto generico da funzione

    Salve a tutti

    Il mio problema è in linea di massima piuttosto semplice...ho:

    public class SynchPort <T>

    contente un metodo send e receive. Tramite questa classe un thread mittente invia (send) un messaggio sincronizzandosi col destinatario (receive) (più o meno problema produttori/consumatori).

    Il tipo generico T mi crea dei problemi nella receive...
    nella send passo l'oggetto per riferimento (ovviamente) e lo assegno alla variabile locale della classe SynchPort

    public void send(Thread Threadref, T info){


    Main.Mutex.P(Threadref);
    this.mittente = Threadref.getName();
    this.data = info;
    Main.SemCond.V();

    }

    Lasciate perdere mutex e semcond che sono 'primitive di sincronizzazione' da me implementate a scopo didattico.

    e fin qui tutto bene...l'oggetto viene passato e puntato da 'data'.

    public void receive(T RecMess , Thread Threadref){

    Main.SemCond.P(Threadref);
    ProcessoRicevente.mittente = this.mittente;
    RecMess = this.data;
    Main.Mutex.V();

    }

    qui la cosa non funziona più (giustamente) perché RecMess è una copia del puntatore passato...
    a prescindere dalla bruttezza della soluzione anche per il campo mittente...una cosa analoga per il tipo generico T non andrebbe ovviamente bene...inoltre NON posso usare return dovendo usufruire per motivi di progetto delle funzioni P e V...
    come faccio a restituire al thread ricevente il generico oggetto? o in questo caso...a far puntare una sua variabile locale al contenuto di this.data?

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613

    Re: Restituire un oggetto generico da funzione

    Originariamente inviato da Cecca
    Salve a tutti

    Il mio problema è in linea di massima piuttosto semplice...ho:

    public class SynchPort <T>

    contente un metodo send e receive. Tramite questa classe un thread mittente invia (send) un messaggio sincronizzandosi col destinatario (receive) (più o meno problema produttori/consumatori).

    Il tipo generico T mi crea dei problemi nella receive...
    nella send passo l'oggetto per riferimento (ovviamente) e lo assegno alla variabile locale della classe SynchPort

    public void send(Thread Threadref, T info){


    Main.Mutex.P(Threadref);
    this.mittente = Threadref.getName();
    this.data = info;
    Main.SemCond.V();

    }

    Lasciate perdere mutex e semcond che sono 'primitive di sincronizzazione' da me implementate a scopo didattico.

    e fin qui tutto bene...l'oggetto viene passato e puntato da 'data'.

    public void receive(T RecMess , Thread Threadref){

    Main.SemCond.P(Threadref);
    ProcessoRicevente.mittente = this.mittente;
    RecMess = this.data;
    Main.Mutex.V();

    }

    qui la cosa non funziona più (giustamente) perché RecMess è una copia del puntatore passato...
    a prescindere dalla bruttezza della soluzione anche per il campo mittente...una cosa analoga per il tipo generico T non andrebbe ovviamente bene...inoltre NON posso usare return dovendo usufruire per motivi di progetto delle funzioni P e V...
    come faccio a restituire al thread ricevente il generico oggetto? o in questo caso...a far puntare una sua variabile locale al contenuto di this.data?
    Se non puoi usare il valore di ritorno del metodo devi modificare il parametro che ti viene passato, ma per fare questo il tipo del parametro dev'essere "predisposto", per esempio con un metodo accessibile al codice che stai scrivendo.
    Se io per assurdo passassi ad un metodo un oggetto che ha solo campi e metodi provati, il metodo puo' provarci finche' vuole ma non modifichera' mai il mio oggetto.

    Il metodo, come dici, riceve una copia del reference, di conseguenza non puo' modificare il reference originale (a parte ovviamente il caso in cui possa accedervi) ma puo' modificare solo l'oggetto a cui i reference puntano, e solo se quest'oggetto lo permette.

    Quindi se la sua variabile locale ha un modificatore d'accesso sufficientemente permissivo, modificala semplicemente e falla riferire alla tua variabile locale.

    (tutto questo ovviamente parlando di oggetti e non tipi primitivi)

    Spero d'aver capito il problema, metti il codice fra tag [CODE] per renderlo piu' leggibile.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2011
    Messaggi
    7
    Grazie per la risposta inanzitutto

    Fondamentalmente quello che mi consigli sarebbe traducibile in C/C++ con l'uso di un puntatore a puntatore...cosa che in java ho 'tradotto' nell'uso di un array ad un elemento...passo il riferimento e il metodo modifica il 'puntatore' all'oggetto al posto [0]...
    La soluzione non è delle più eleganti...ma non mi viene in mente altro...

  4. #4
    Basterebbe anche una classe wrapper che implementi i metodi getter e setter per il tuo recmess, senza scomodare gli array.
    ...

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2011
    Messaggi
    7
    penso che mi creerebbe dei problemi per tutto il resto...comunque grazie mille ancora!

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2009
    Messaggi
    613
    Originariamente inviato da Caiodark
    Basterebbe anche una classe wrapper che implementi i metodi getter e setter per il tuo recmess, senza scomodare gli array.
    Alla fine e' piu' o meno la stessa cosa, ha usato un contenitore gia' pronto (array) come wrapper. E come dice la soluzione non e' certo molto pulita, IMHO nemmeno usando una classe wrapper ad hoc.

    Secondo me c'e' un metodo che a mio parere e' piu' pulito: dato che ci si aspetta un oggetto che dovrebbe permettere di essere settato tramite un un altro oggetto, si potrebbe definire un'interfaccia generica ed usare questa come tipo di parametro nel metodo in questione.

    codice:
    interface Interface<T> {
    	
    	void set(T t);
    	
    }
    codice:
    class SynchPort<T> {
    
    	T data;  // immagino tu abbia una cosa del genere, qui o nel metodo...
    
    	public void send(Thread Threadref, Interface<T> info) {
    		// fai quello che devi, poi:
    		info.set(data);
    	}
    
    }
    e l'implementazione dell'interfaccia sara' qualcosa del genere

    codice:
    class Person implements Interface<Person> {
    
    	String name;
    	int age;
    
    	public void set(Person person) {
    		name = person.name;
    		age = person.age;
    	}
    
    }
    In questo modo sei sicuro di non poter combinare danni, sempre che l'interfaccia sia stata implementata correttamente. Se qualcuno ha idee migliori...
    Non ho controllato neanche se Java prevede gia' un'interfaccia del genere

  7. #7
    Kaamos, a me la tua idea piace!
    ...

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.