Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Fable e Sol a confronto: due cartoni animati creati su un PC con RTX 3090
Fable e Sol a confronto: due cartoni animati creati su un PC con RTX 3090
Ho affidato ai due modelli lo stesso mestiere ma non lo stesso identico prompt: trasformare una storia illustrata in un video usando una RTX 3090 e modelli locali. Ne sono usciti due film, due applicazioni e due idee opposte di efficienza. Fucina, progettata con Fable 5, colpisce di più nei primi secondi. Storyboard Studio, costruito con ChatGPT/Codex, regge meglio sulla distanza e vince il confronto complessivo, ma di stretta misura
Il tablet rugged leggero e sottile: Lenovo ThinkTab X11 offre resistenza, doppia USB-C e batteria rimovibile
Il tablet rugged leggero e sottile: Lenovo ThinkTab X11 offre resistenza, doppia USB-C e batteria rimovibile
Lenovo ha lanciato il ThinkTab X11 rimettendo piede nel segmento dei tablet Android con il marchio Think dopo oltre un decennio di assenza. Il risultato è un dispositivo che prende una direzione precisa: massima dotazione funzionale, costruzione resistente, autonomia fuori dagli schemi
AMD Advancing AI 2026: l'hardware AMD per le elaborazioni IA del futuro, tra GPU, CPU e robot
AMD Advancing AI 2026: l'hardware AMD per le elaborazioni IA del futuro, tra GPU, CPU e robot
AMD Advancing AI è l'appuntamento annuale con il quale l'azienda americana mostra quelle che sono le proprie novità dal versante datacenter. Tra piattaforma Helios, GPU Instinct MI455X e processori EPYC di sesta generazione tutto quello che serve per processare l'IA sempre più complessa ed esigente
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 26-10-2001, 16:26   #1
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
C++: Questa proprio non la sapevo

Guardate questo codice:

#include <iostream.h>
class C1 {
virtual void print () { cout << "print() di C1\n"; }
public:
C1 () { print(); }
void do_print () { print (); }
};

class C2: public C1 {
void print () { cout << "print() di C2\n"; }
};

int main() {
C2 C;
C.do_print();
return 0;
}

L'output del programma è:
print() di C1
print() di C2
ed è uguale sia sul g++ 2.91, g++ 2.96 che sul visual c.
Succo: nei costruttori di classe le funzioni virtuali a quanto pare non sono usate come tali - qualcuno ne sa qualcosa di più a riguardo?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 26-10-2001, 17:11   #2
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Sinceramente non mi ricordo come funziona l'ereditariatà sul costruttore di default...in ogni caso sembra che tu abbia ereditato anche quello...
Infatti con "C2 C;" richiami il costruttore di default di C2 erediatato da C1 e poi con "do_print()" che è ereditata da C1 richiami la print() di C2 come è sicuramente giusto (visto che l'stanza è di tipo C2)...

Comunque funziona allo stesso modo anche in VC++...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 26-10-2001, 19:23   #3
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
No, non è così, il costruttore di C1 viene chiamato prima di quello di default di C2, è normale che sia così. Il problema è che a quanto sembra, C viene inizialmente costruito come C1, poi come C2. Solo questo può spiegare il fatto che, se il costruttore chiama una funzione virtuale, non viene chiamata quella effettiva della classe di appartenenza.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 02:28   #4
Black imp
Senior Member
 
Iscritto dal: Nov 2000
Città: MILANO
Messaggi: 2662
.
Black imp è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 02:44   #5
Black imp
Senior Member
 
Iscritto dal: Nov 2000
Città: MILANO
Messaggi: 2662
la chiamata a print è fatta in una funzione di C1 e chiama un'altra funzione dello scope di C1. Quindi mi sembra normale che NON possa vedere un elemento funzione di C2.
facciamo un altro esempio che scrivo adesso sperando di non confonderti le idee:

class A {

public:
A();
virtual print() {printf("classe A\n"};
};

class Bublic A {

public:
print() { printf("classe B\n"); };

}


int main() {

A a;
a.print();
B b;
b.print();

}

deve stamparti "classe A" e poi "classe B" e tutto funziona correttamente secondo le regole. Nel tuo esempio la funzione che ridefinisci innanzi tutto è privata e non può essere ridefinita perchè la classe derivata può accedere solo ai membri pubblc della super classe. In secondo luogo tu chiami esplicitamente una funzione della superclasse - NON della derivata - e che perciò non può " vedere " nello scope della derivata - ci mancherebbe - e chiama corettamente la funzione print() del SUO scope. Occhio perchè questo esempio è molto incasinato. Non si usa in questo modo il polimorfismo. Inoltre usa sempre i puntatori quando hai a che fare con il polimorfismo: altrimenti non serve a nulla.

Ad es. tu sai che devi tenere un elenco di oggetti Sensor in un tuo programma ma non sai ancora se questi oggetti in particolare saranno dei TouchSensor o dei LightSensor ecc. Allora tieni un vettore di puntatori a Sensor e per ognuno a run time allocherai la giusta classe derivata. In questo modo, chiamando i metodi virtuali - stiamo parlando di metodi virtuali NON puri ovviamente - della classe Sensor, verranno in realtà invocati i corrispettivi metodi della derivata:


Sensor* lista[10];

lista[0]= new LightSensor();

ecc.
Black imp è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 09:36   #6
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
la chiamata a print è fatta in una funzione di C1 e chiama un'altra funzione dello scope di C1. Quindi mi sembra normale che NON possa vedere un elemento funzione di C2.
No, questo non è corretto, in quanto print è dichiarata virtuale, e quindi soggetta a polimorfismo in caso di ereditarierà. Infatti, come puoi vedere, do_print() è una funzione di C1 ma è in grado di invocare la print() polimorfa corretta, ovvero quella di C2 nell'esempio. A quanto pare solo i costruttori fanno eccezione a questa regola, ma non ne capisco il motivo (sicuramente ce n'è uno)
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 13:01   #7
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Non capisco qual è il problema...la print di C1 è virtuale...quindi, visto che è definita anche la print di C2 nella vtable della classe è presente il puntatore alla funzione print di C2...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 13:39   #8
/\/\@®¢Ø
Bannato
 
L'Avatar di /\/\@®¢Ø
 
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
Anche a me e' accaduto un problema simile,
solo che la funzione nella classe base non era definita, e quindi il programma crashava con un "Pure virtual method called" o qualcosa di simile ( provare per credere ).
Probabilmente ogni costruttore provvede solamente ad aggiungere ( ovvero sovrascrivere ) nella virtual table i metodi ridefiniti. QUando sei nel costruttore della classe base di conseguenza, non hai nessun metodo ridefinito.
Perche' non hanno deciso di scrivere subito la virtual table completa ?
Secondo me l'hanno fatto per poter riutilizzare i costruttori delle classi basi senza doverli spezzare in piu' parti, a vantaggio dell'efficienza.
( Anche se quest'ultima cosa e' solo una mia ipotesi ).
/\/\@®¢Ø è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 13:41   #9
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Non capisco qual è il problema...la print di C1 è virtuale...quindi, visto che è definita anche la print di C2 nella vtable della classe è presente il puntatore alla funzione print di C2...
Appunto: tutte le funzioni di C1 invoncano la funzione "giusta" di C2; tutte tranne costruttore e distruttore di C1...è il "perchè" che mi sfugge. Questo vuol dire inoltre che non puoi definire una classe astratta nella quale una funzione virtuale pura (magari da implementare fisicamente in una classe che eredita) viene invocata dal costruttore.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 13:44   #10
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
Originariamente inviato da /\/\@®¢Ø
QUando sei nel costruttore della classe base di conseguenza, non hai nessun metodo ridefinito.
Perche' non hanno deciso di scrivere subito la virtual table completa ?
Secondo me l'hanno fatto per poter riutilizzare i costruttori delle classi basi senza doverli spezzare in piu' parti, a vantaggio dell'efficienza.
( Anche se quest'ultima cosa e' solo una mia ipotesi ).
Non credo che si tratti di efficienza, in quanto aggiornare la vtable prima o dopo la chiamata al costruttore non cambia la velocità. Credo che tutto dipenda da qualche specifica del c++ della quale però mi sfugge la motivazione...
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 14:00   #11
/\/\@®¢Ø
Bannato
 
L'Avatar di /\/\@®¢Ø
 
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
Cerco di spiegarmi meglio:

La 'costruzione' di un oggetto richiede vari cose giusto ( 'aggiustamento' )della vtable esecuzione del costruttore definito dall'utente e cosi' via ).
Ora se io volessi avere da subito la virtual table "esatta", dovrei riuscire a effettuare solo parte di queste operazioni, in particolare escludere la scrittura della vtable da parte dei costruttori derivati, ( perche' altrimenti la stessa tornerebbe 'carente' ). E' probabile che questo sia di difficile esecuzione: se pensi che potrei aver derivato un oggetto che mi arriva da una libreria esterna, questo vuol dire che ogni libreria dovrebbe esportare una certa quantita' di funzioni ( o comunque di informazioni ) da chiamare in caso di derivazione.
/\/\@®¢Ø è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 14:32   #12
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
mmm questo mi sembra già più convincente, anche se continuo ad avere dei dubbi sul fatto che modi alternativi siano impossibili da gestire
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 18:15   #13
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Posso provare a dare una spiegazione...un po' a occhio...

Implementando il costruttore di default per C2 viene lo stesso richiamato il costruttore di default di C1...
Quindi al momento della chiamata del costruttore di C1 si tratta di costruire un oggetto di tipo C1...la cui vtable verrà poi sovrascritta dalla creazione dell'oggetto C2 che viene derivato da C1 di cui eredita la parte pubblica...

Quindi secondo me il compilatore opera in questo modo...

Crea un'istanza di C1 e ne chiama il costruttore (a questo punto l'oggetto è ancora di tipo C1...ed è per questo che viene chiamata la print di C1)...l'istanza di C2 eredita i membri e le funzioni pubbliche di C1...viene modificata la vtable (viene sovrascritta l'entry di print())...poi successivamente viene chiamato il costruttore di C2...

Modificando il codice in questo modo si vede che quello che avviene sembra essere questo...

#include <iostream.h>

class C1 {
virtual void print () { cout << "print() di C1\n"; }
public:
C1 () { print(); }

void do_print () { print (); }
};

class C2: public C1 {
void print () { cout << "print() di C2\n"; }
public :
C2 () {print();};
};

int main() {
C2 C;
C.do_print();

return 0;
}
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 18:31   #14
Black imp
Senior Member
 
Iscritto dal: Nov 2000
Città: MILANO
Messaggi: 2662
MA RAGAZZI!!! ho capito adesso la domanda. MA NON SCHERZIAMO!! quando ereditate una classe VIENE SEMPRE CHIAMATO IL COSTRUTTORE DELLA SUPERCLASSE se no non funzionerebbe più niente. E che senso avrebbe?

per IL_sensine: non sono sicuro di come funzioni in questo caso. ripasserò un po'. comunque se chiamate q.sa che sta solo nella superclasse questo NON può vedere la parte 'aggiunta ' ereditando.
Black imp è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 19:10   #15
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
MA RAGAZZI!!! ho capito adesso la domanda. MA NON SCHERZIAMO!! quando ereditate una classe VIENE SEMPRE CHIAMATO IL COSTRUTTORE DELLA SUPERCLASSE se no non funzionerebbe più niente. E che senso avrebbe?
Questo è ovvio, non è in discussione. C1::C1() viene sempre chiamato.

Quote:
per IL_sensine
(ilsensine svp)

Quote:
se chiamate q.sa che sta solo nella superclasse questo NON può vedere la parte 'aggiunta ' ereditando.
Qui non stiamo parlando di parti aggiunte, ma di parti polimorfe. Come vedi, do_print() sta solo in C1 ma chiama comunque correttamente la funzione (polimorfa, in quanto virtuale in C1 e ridefinita in C2) implementata in C2.

Il problema (che cionci e /\/\@®¢Ø) hanno intuito) a quanto pare è che la vtable viene costruita mano mano che vengono chiamati i costruttori delle classi, e non _prima_ come mi sarei aspettato. Tutto qui.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 19:15   #16
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Certo...
Al momento della chiamata del costruttore di C1 l'istanza è a tutti gli effetti della classe C1...poi successivamente viene modificata la vtable al momento dell'allocazione di C2...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 27-10-2001, 19:20   #17
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
poi successivamente viene modificata la vtable al momento dell'allocazione di C2...
a questo punto direi: "al momento della trasformazione in C2". In effetti quello che accade sembra essere proprio questo, anche se il termine è improprio.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
Old 28-10-2001, 02:50   #18
Black imp
Senior Member
 
Iscritto dal: Nov 2000
Città: MILANO
Messaggi: 2662
allora non avevo capito. forse perchè questo mi sembrava più ovvio mentre in realtà mi sono accorto che non mi ricordo bene altri aspetti a dire il vero
Black imp è offline   Rispondi citando il messaggio o parte di esso
Old 28-10-2001, 02:59   #19
Black imp
Senior Member
 
Iscritto dal: Nov 2000
Città: MILANO
Messaggi: 2662
AAAAAHHHH adesso ho capito ancora meglio! in sostanza il problema è che secondo voi non doveva invocare la print di C1 durante l'invocazione al costruttore, perchè questa è già stata ridefinita. Mhhh beh quando viene chiamato il costruttore della super classe - vale anche per una catena di ereditarietà - l'oggetto modifica tipo man mano: se C eredita da B che eredita da A, quando si crea un oggetto C, prima viene costruito un oggetto A poi esteso a B poi esteso a C. quindi mi sembra coerente che durante l'esecuzione del costruttore di C1 chiami ancora la print di C1. Non so se questo in effetti sia un limite anzi. Direi che se si cercasse di fare veramente una cosa come nell'esempio con quell'intento, sarebbe sbagliata la scelta di ereditare C2 da C1 - non sto criticando chi lo ha scritto - non vi pare?
Black imp è offline   Rispondi citando il messaggio o parte di esso
Old 28-10-2001, 09:02   #20
ilsensine
Senior Member
 
L'Avatar di ilsensine
 
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
Quote:
quindi mi sembra coerente che durante l'esecuzione del costruttore di C1 chiami ancora la print di C1.
Assodato che la costruzione di una classe derivata avviene per gradi, è coerente.
Quote:
Non so se questo in effetti sia un limite anzi.
Forse è un limite. Supponi a titolo di esempio di definire una classe generica Numero, il cui costruttore chiami una funzione virtuale che alloca la memoria necessaria a contenere il numero. Poichè ancora non è stato definito di che numero si tratti e di quanta memoria sia necessaria per contenerlo, tale funzione può essere definita virtuale pura (ovviamente, da ciò che abbiamo visto, non è possibile). Poi ogni derivazione di Numero (ad es. Intero, Complesso ecc.) potrebbe ridefinire una propria istanza di tale funzione per allocare la memoria necessaria. Se la vtable fosse stata aggiornata prima della chiamata alla catena di costruttori, una cosa del genere avrebbe funzionato. Prendiamo atto che però non è così.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al
andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12
ilsensine è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Fable e Sol a confronto: due cartoni animati creati su un PC con RTX 3090 Fable e Sol a confronto: due cartoni animati cre...
Il tablet rugged leggero e sottile: Lenovo ThinkTab X11 offre resistenza, doppia USB-C e batteria rimovibile Il tablet rugged leggero e sottile: Lenovo Think...
AMD Advancing AI 2026: l'hardware AMD per le elaborazioni IA del futuro, tra GPU, CPU e robot AMD Advancing AI 2026: l'hardware AMD per le ela...
Tascabile e con Android: BOOX Go 6 Gen II è diverso da tutti gli altri e-reader Tascabile e con Android: BOOX Go 6 Gen II &egrav...
Recensione Lenovo Idea Tab Plus: il tablet da 12 pollici che costa meno di 300 euro Recensione Lenovo Idea Tab Plus: il tablet da 12...
Tre astronauti rientrano dalla ISS: la S...
Kimi K3 ha trovato 19 zero-day in Redis ...
Aggiungere un acceleratore IA per data c...
Debian valuta lo stop totale ai contribu...
Is Huawei Building Its Own DRAM Fab?
QNAP lancia i nuovi NAS TS-262A e TS-462...
E4 Computer Engineering e EuroHPC JU uni...
World di Sam Altman raccoglie 52,5 milio...
AMD prepara il futuro delle CPU Ryzen: Z...
Intel fa marcia indietro: torna la tecno...
Honor ROBOT PHONE ha una data d'uscita: ...
TSMC accelera sulla produzione a 2 nm: u...
Diritto alla riparazione, dal 31 luglio ...
WhatsApp introduce il conteggio privato ...
Lenovo IdeaPad Slim 3 a 499,90€: ecco pe...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 14:19.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v