PDA

Visualizza versione completa : VB6 - Tipi definiti dall'utente nelle Classi


LeleB
21-05-2003, 16.03.20
Ciao a tutti,
è un po' che non bazzico da queste parti...male!!
vi scrivo per sottoporvi un problema un po' ostico..

All'interno di un modulo di classe ho dei tipi di dato da me definiti es.:

Private Type MioDato
X(5) As Integer
Y As String
End Type

Private m_MioDato As MioDato

chiaramente sono privati essendo delle proprietà dell'oggetto che non devono
essere visibili
all'esterno.

Ora, se tento di creare una Property di questo tipo:

Public Property Get Dato(Optional Z As String) As MioDato
....
....
Dato = m_MioDato

End Property

Public Property Let Dato(ByRef NewDato As MioDato)
m_MioDato.X = NewDato.X
m_MioDato.Y = NewDato.Y
End Property

Mi ritorna questo errore di compilazione:

"Impossibile utilizzare i tipi Enum e i tipi definiti dall'utente privati
come parametri o tipi restituiti per routine pubbliche,
membri pubblici di dati o campi di tipi pubblici definiti dall'utente"

In più, all'interno della classe ho dei metodi così composti:

Private Function MioMetodo (ByRef Dato As MioDato, Optional K As Integer) As
Integer
....
End Function

E qui l'errore è:

"Solo i tipi pubblici definiti dall'utente definiti in moduli di oggetto
pubblici possono essere utilizzati come parametri o tipi restituiti per
routine
pubbliche di moduli di classe o come campi di tipi pubblici definiti
dall'utente."

Sinceramente VB non è un gran ambiente..preferisco il caro buon vecchio C++!!

Spero di essermi spiegato e che mi possiate dare qualche dritta!!

Tnx a lot!
LeleB.

LoryOne
21-05-2003, 17.18.42
Ehhhhh caro amico mio, ogni ambiente di sviluppo ha le sue regole, però con un po di pazienza si risolve tutto
Crea un nuovo progetto con un form ed un modulo di classe

Nel modulo di classe scrivi il seguente codice:


Private Type MioDato
X(0 To 5) As Integer
Y As String
End Type

Private m_miodato As MioDato

Public Property Let DatoY(ByVal vData As String)
m_miodato.Y = vData
End Property

Public Property Get DatoY() As String
DatoY = m_miodato.Y
End Property

Public Property Get MaxDatoX() As Integer
MaxDatoX = UBound(m_miodato.X())
End Property

Public Property Get MinDatoX() As Integer
MinDatoX = LBound(m_miodato.X())
End Property

Public Property Let DatoX(ByVal Id As Integer, ByVal vData As Integer)
m_miodato.X(Id) = vData
End Property

Public Property Get DatoX(ByVal Id As Integer) As Integer
DatoX = m_miodato.X(Id)
End Property


Nel form scrivi quest'altro codice.


Dim Classe As New ClasseMio

Private Sub Command1_Click()
Dim Ty As Integer, Yt As Integer, T As Integer

With Classe
Ty = .MaxDatoX
Yt = .MinDatoX
For T = Yt To Ty
.DatoX(T) = T
Next
.DatoY = "Ecco fatto !"

Ty = 0

While Ty <= .MaxDatoX
Print .DatoX(Ty)
Ty = Ty + 1
Wend

Print .DatoY
End With
End Sub


Ricorda che la prima regola è:
MAI GETTARE LA SPUGNA
La seconda è:
ADATTARSI E RAGGIUNGERE LO SCOPO (Sergente Gunny Higway a rapporto, signore !).

Saluti. ;: :)

LeleB
21-05-2003, 17.59.20
Originariamente inviato da LoryOne
Ehhhhh caro amico mio, ogni ambiente di sviluppo ha le sue regole, però con un po di pazienza si risolve tutto

Lo so, lo so...il mio era solo un piccolo sfoghino perchè non riuscivo a venire a capo di questo inghippo (chiedo scusa a tutti i sostenitori di VB)!!

Dal codice che mi hai scritto noto che la soluzione è quella di "scomporre" la struttura e, sinceramente, mi era venuta anche a me un'idea simile (non voglio peccare di presunzione)..
Nella speranza avevo anche provato a passarne una come argomento per riferimento così da modificare direttamente l'istanza passata (cosa mooolto brutta)..ma niente :(
L'altro mio grosso problema ora è che di strutture ne ho parecchie ed anche abbastanza articolate...quindi se dovessi fare così dovrei scrivere un bel po' di codice!!
E' chiaro che se l'unico modo è questo mi rimbocco le maniche e mi metto a scrivere..ma speravo ci fosse un modo per far ritornare una struttura ad una funzione...


[i]
Ricorda che la prima regola è:
MAI GETTARE LA SPUGNA
La seconda è:
ADATTARSI E RAGGIUNGERE LO SCOPO (Sergente Gunny Higway a rapporto, signore !).

Saluti. ;: :) [/B]

Eheh..le conosco anche troppo bene queste regole!! ;)

Ti ringrazio molto!!
LeleB.

LoryOne
21-05-2003, 18.04.56
[quote]
speravo ci fosse un modo per far ritornare una struttura ad una funzione...
[\quote]

...l'avevo capito.
Fammece pensà...

LoryOne
21-05-2003, 18.05.40
Azz, confusi "/" con "\".

LeleB
21-05-2003, 18.35.30
Il fatto è che sono quei due errori che mi fanno riflettere:

"Impossibile utilizzare i tipi Enum e i tipi definiti dall'utente privati come parametri o tipi restituiti per routine pubbliche,
membri pubblici di dati o campi di tipi pubblici definiti dall'utente"

Lui dice: se la struttura è privata come fai a restituirla all'esterno?
Mi verrebbe da dire: dichiarando all'esterno un oggetto costruito dalla medesima struttura.

"Solo i tipi pubblici definiti dall'utente definiti in moduli di oggetto pubblici possono essere utilizzati come parametri o tipi restituiti per routine pubbliche di moduli di classe o come campi di tipi pubblici definiti dall'utente."

E qui, da quel che posso capire, mi dice: Non puoi dichiarare un tipo Privato se lo vuoi passare ad una funzione in una classe!
E allora la classe così come l'ho pensata non serve a nulla! :(

Cmq secondo me un modo ci deve essere.. :):)

P8257 WebMaster
21-05-2003, 18.46.59
Permettetemi di fare una considerazione..

Nel post con cui hai aperto questo thread dicevi che ti trovi meglio con C++ .. forse i problemi che riscontri sono dovuti al fatto che "richiedi" a VB una potenza nel trattare ed operare con oggetti, strutture e classi che in realtà non ha.

Volevo sottolineare che VB (senza andare contro ai sostenitori, ovviamente) ha solo una infarinatura di OOP e forse appunto non dispone della potenza che richiedi. Detto questo, non vuol dire che con qualche "giro" inusuale o qualche accorgimento, come Lory ha dimostrato, non si possa venire presto a capo di questi problemi .. anche se magari ti comporterà il dover scrivere qualche linea in più.

Bye :cool:

LoryOne
21-05-2003, 19.07.32
No, direi proprio di no.
L'unica cosa che son riuscito a fare è :


'---Codice di Classe
Private Type Pippo
a(0 to 5) as Integer
b As String
End Type

Friend Property Get Pluto() As Pippo

End Property


Così si potrebbe richiamare come Classe.Pluto.a, ma il compilatore da errore.
Però a pensarci bene c'è qualcosa di errato nel tuo modo di ragionare.
La mia domanda è:
"Perchè vuoi ricavare i valori di una struttura dati che di per se è Private all'interno della classe e quindi vive solo ed esclusivamente li ?[\b]"

E' vero, ci sono funzioni in C++ nelle dll di Windows che accettano/modificano strutture dati ma tu per poterne usufruire hai bisogno di ri-dichiarare tali strutture.
Facci un esempio:

1)Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Questa funzione presumibilmnte in C++ riempie lpRect con le coordinate dell' area sottoscritta dalla finestra identficata con hwnd.
Per poter usufruire di tale funzione, devi definire il tipo RECT come

Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As LongEnd Type
La struttura in VB non può differire da quella definita in C++.

2)Private Declare Function SetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Questa funzione presumibilmnte in C++ sposta la finestra identificata con hwnd in una nuova posizione definendone altri attributi.

Private Type POINTAPI
x As Long
y As LongEnd Type

Private Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RectEnd Type
Anche qui, la struttura in VB non può differire da quella definita in C++.
Alla luce delle considerazioni sopraesposte affermo che è [b]il concetto ad essere errato.

LoryOne
21-05-2003, 20.07.39
Le classi in VB non ne vogliono proprio sapere di Public Type, solo di Private Type.
I moduli invece si, possono definire Public Type e/o Private Type.
In fondo che ti frega creare una classe ?
Creati un modulo e "vedilo come classe", ossia come parte di codice da aggiungere ai tuoi progetti.
Lo so, sarebbe bello creare una dll ma per farne che ?
Usarla in C++ ? In Delphi ?
La useresti solo nei tuoi programmi in VB, no ?
Allora lascia che l'exe sia un po più lungo e non starti a scervellare troppo...Vuoi usare VB ?...Bene quello ti offre e quello usa !

LoryOne
22-05-2003, 08.56.32
La notte porta consiglio...

Ho aggiunto nella classe:
[code]
Friend Property Get Dato() As MioDato
Dato = m_miodato
End Property
[\code]

Ho aggiunto nel form:
[code]
Private Type MioDato
X(0 To 5) As Integer
Y As String
End Type
[\code]

All'interno del form, dopo aver assegnato i valori ad X e ad Y, posso utilizzare la seguente sintassi:
Print Classe.Dato.x(0)
Print Classe.Dato.x(1), ecc

...avrai notato che HO DOVUTO INSERIRE LA STESSA STRUTTURA (uguale a quella definita nella classe) nel form

Il tutto come ho voluto dimostrare nel 2° post prima di questo.;) :)

LoryOne
22-05-2003, 09.00.04
..continuo a confondere "/" con "\".
Sarà che sono ubriaco già di primo mattino...Sarà che ho cambiato gli occhiali...Sarà che sono fuori, mah...scusate

LeleB
22-05-2003, 09.14.04
Originariamente inviato da P8257 WebMaster
Permettetemi di fare una considerazione..

Nel post con cui hai aperto questo thread dicevi che ti trovi meglio con C++ .. forse i problemi che riscontri sono dovuti al fatto che "richiedi" a VB una potenza nel trattare ed operare con oggetti, strutture e classi che in realtà non ha.

Volevo sottolineare che VB (senza andare contro ai sostenitori, ovviamente) ha solo una infarinatura di OOP e forse appunto non dispone della potenza che richiedi.

Ciao, vedi il fatto è che non ho mai programmato con VB a "questi livelli", perciò non mi sono mai dovuto scontrare con i suoi limiti.
Secondo me è un ambiente adatto per sviluppare applicazioni "semplici" (che non è sinonimo di banali) in un breve lasso di tempo ma come giustamente dici tu se hai bisogno di un po' di potenza e versatilità in più... :)

Detto questo, non vuol dire che con qualche "giro" inusuale o qualche accorgimento, come Lory ha dimostrato, non si possa venire presto a capo di questi problemi .. anche se magari ti comporterà il dover scrivere qualche linea in più.

Bye :cool:

Sono d'accordissimo, il mio "astio" a scrivere più codice non è un fatto di pigrizia, ma di praticità (sai, quando devi consegnare dei lavori in tempi prestabiliti..!!)

LeleB
22-05-2003, 09.26.42
Originariamente inviato da LoryOne
Però a pensarci bene c'è qualcosa di errato nel tuo modo di ragionare.
La mia domanda è:
"Perchè vuoi ricavare i valori di una struttura dati che di per se è Private all'interno della classe e quindi vive solo ed esclusivamente li ?"

E' vero, ci sono funzioni in C++ nelle dll di Windows che accettano/modificano strutture dati ma tu per poterne usufruire hai bisogno di ri-dichiarare tali strutture.
...
Alla luce delle considerazioni sopraesposte affermo che è il concetto ad essere errato.

Tutto sta nel concetto di incapsulamento.
Anche se una struttura è un tipo di dato complesso, è pur sempre un tipo di dato e quindi deve essere "usato" come tale:

Se in una classe dichiaro che una funzione ritorna un LONG, quando la richiamo devo dichiarare una variabile LONG, perciò se ho una funzine che ritorna un MioDato dovrò dichiarare una variabile MioDato, con l'unica differenza che per un LONG è il sistema a sapere tutto mentre in MioDato sono io che devo sobbarcarmi il compito di definirlo.

In VB l'incapsulamento non si riesce a definire molto bene..

Ciao.

P8257 WebMaster
22-05-2003, 10.48.13
LeleB ha scritto:

In VB l'incapsulamento non si riesce a definire molto bene..

Ciao.

Esatto .. perchè VB non è nato per queste cose .. e non ci quaglia molto .. diverso è il discorso per VB.NET.

Bye :cool:

LoryOne
22-05-2003, 11.19.41
[quote]
Se in una classe dichiaro che una funzione ritorna un LONG, quando la richiamo devo dichiarare una variabile LONG, perciò se ho una funzine che ritorna un MioDato dovrò dichiarare una variabile MioDato, con l'unica differenza che per un LONG è il sistema a sapere tutto mentre in MioDato sono io che devo sobbarcarmi il compito di definirlo
[\quote]

Esatto, forse stiamo dicendo la stessa cosa.
Se tu definisci in una classe una struttura Private, questa struttura sarà gestibile da routines interne/esterne (Public Property,Friend Property) alla classe.
Se vuoi far accesso ad una struttura interna alla classe, senza definirla nel form o nel modulo, [b]non puoi[\b] , in quanto nelle classi VB IMPONE che tale struttura sia Private.

Tu puoi passare una struttura ad una classe, purchè la stessa struttura sia definita in modo identico nel codice che la richiama.
Ma allora se il tuo scopo è quello di creare una [b]classe riutilizzabile[\b], sei costretto a cambiar strada ed a ragionare sui moduli, non sulle classi.

Tutto ciò che vuoi relaizzare (e come lo vuoi realizzare) sarà fattibilissimo, senza utilizzare property.
L'unica pecca è che nei tuoi progetti dovrai inserire un modulo (anch' esso riutilizzabile) invece di un modulo di classe.

E' un casino persino spiegarlo.
Spero di aver reso l'idea ,più che altro, di aver scritto in italiano comprensibile) !!! :) :) :)

Saluti.

Ps: Per certe cose preferisco anch'io C++ ;)

LoryOne
22-05-2003, 11.20.26
...sempre più ubriaco.

P8257 WebMaster
22-05-2003, 12.04.03
LoryOne ha scritto:
...sempre più ubriaco.

Le barreeeeeee :D.. :eek: .. :D ..

Bye :cool: