Discussione:
Interfacce in C++
(troppo vecchio per rispondere)
Giacomino
2006-10-18 10:11:01 UTC
Permalink
Salve a tutti
In C++ non esiste il costrutto interface come in Java, ma ho letto che
è possibile "simularlo" attraverso l'eredità virtuale di una classe
astratta pura. Mi spiego meglio con un esempio:

// la mia interfaccia
class Interface
{
public:
virtuual void methodA() = 0;
virtual int methodB(int x, int y) = 0;
};

// la mia classe Derived estende una classe base ed implementa un
interfaccia
class Derived : public Base, public virtual Interface
{ ... };

Mi chiedo:
- è questo il modo (più) giusto per raggiungere l'obiettivo
prefissatomi?
- dal punto di vista sintattico, ho qualche implicazione?
- quali sono le implicazioni in termini di performance e di spazio
occupato?

Spero di essere stato abbastanza chiaro. Grazie anticipatamente.
kanze
2006-10-18 12:08:43 UTC
Permalink
Post by Giacomino
In C++ non esiste il costrutto interface come in Java, ma ho letto che
è possibile "simularlo" attraverso l'eredità virtuale di una classe
astratta pura.
Direbbe piùtosto che in C++, non c'è le limitazioni artificiale
di Java, dunque, non c'è bisogna di work-around interface nel
linguaggio.
Post by Giacomino
// la mia interfaccia
class Interface
{
virtuual void methodA() = 0;
virtual int methodB(int x, int y) = 0;
Metterei anche:
virtual ~Interface() {}
Post by Giacomino
};
// la mia classe Derived estende una classe base ed implementa un
interfaccia
class Derived : public Base, public virtual Interface
{ ... };
- è questo il modo (più) giusto per raggiungere l'obiettivo
prefissatomi?
Non daverro. Servi per i callback ed altri "inversion of control
flow", ma se no, è abbastanza raro d'aver delle funzionni
publiche virtuali. In generale, definire una interface vuol dire
definire un contratto, che si fa:

class InterfaceWithContract
{
public:
virtual ~InterfaceWithContract() {}

void functionA()
{
// assert delle precondizioni...
doFunctionA() ;
// assert delle postcondizioni...
}
// ...

private:
virtual void doFunctionA() = 0 ;
// ...
} ;

In fatti, anche in Java, se vuoi un codice robusta, si fa cosi
(solo che le funzionni private virtuella devono essere
protected), con classe abstract, e non con interface. (Ma il
Java non serva tanto quando bisogna di robustezza.)
Post by Giacomino
- dal punto di vista sintattico, ho qualche implicazione?
Che implicazioni. È un eritaggio, come tutti gli eritaggi.
Post by Giacomino
- quali sono le implicazioni in termini di performance e di spazio
occupato?
Dipende dell'implementazione, ma in generale, costa meno che un
interface di Java.

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nicola Musatti
2006-10-18 12:14:49 UTC
Permalink
Post by Giacomino
Salve a tutti
In C++ non esiste il costrutto interface come in Java, ma ho letto che
è possibile "simularlo" attraverso l'eredità virtuale di una classe
astratta pura.
Oppure e' Java che da un nome diverso ad un particolare tipo di classe.
Comunque quello che dici e' corretto.
Post by Giacomino
// la mia interfaccia
class Interface
{
virtuual void methodA() = 0;
virtual int methodB(int x, int y) = 0;
};
// la mia classe Derived estende una classe base ed implementa un
interfaccia
class Derived : public Base, public virtual Interface
{ ... };
In C++ si dice semplicemente che Derived ha due classi base, una
pubblica e l'altra pubblica virtuale.
Post by Giacomino
- è questo il modo (più) giusto per raggiungere l'obiettivo
prefissatomi?
Secondo me e' l'obiettivo prefissato che e' sbagliato: stai cercando di
ritrovare in C++ le cose che conosci in Java, mentre faresti meglio ad
imparare direttamente "usi e costumi" del C++.
Post by Giacomino
- dal punto di vista sintattico, ho qualche implicazione?
Cioe'?
Post by Giacomino
- quali sono le implicazioni in termini di performance e di spazio
occupato?
Teoricamente esattamente le stesse del fare le stesse cose in Java.

Ciao,
Nicola
Giacomino
2006-10-18 12:58:28 UTC
Permalink
Post by Nicola Musatti
Secondo me e' l'obiettivo prefissato che e' sbagliato: stai cercando di
ritrovare in C++ le cose che conosci in Java, mentre faresti meglio ad
imparare direttamente "usi e costumi" del C++.
Sicuramente gli "usi e costumi" del C++ sono differenti da quelli di
Java (il fatto che abbia dimenticato il distruttore virtuale è la
prova di abitudini legati all'utilizzo del secondo) e che bisogna
esserne a conoscenza prima di utilizzare il linguaggio.
Nonostante questo il concetto di interfaccia (mediante il quale ci si
assicura che un determinato set di metodi sia presente in un oggetto)
è molto comodo e gradito. Mi sembra invece che in C++ l'eredità
multipla porta ad una duplicazione dei metodi aventi la stessa
signature presenti in sottoclassi diverse, con la necessità di dover
disambiguare. Cioè
se ho

class Base
{
public:
virtual void methodA() { ... }
virtual void ~Base() { }
};

class Interface
{
public:
virtual void methodA() = 0;
virtual void ~Interface() { }
};

class Derived : public Base, public virtual Interface
{ ... };

Derived* d;
...
d->methodA();

ottengo un errore? Oppure devo disambiguare con i risolutori?
Giacomino
2006-10-18 13:04:16 UTC
Permalink
Post by Giacomino
virtual void ~Base() { }
Chiedo venia per il "void" sul distruttore.
Post by Giacomino
Derived* d;
...
d->methodA();
ottengo un errore? Oppure devo disambiguare con i risolutori?
Nell'esempio, vorrei che venisse invocata l'implementazione di
Base::methodA()

Spero di essere stato chiaro.
Nicola Musatti
2006-10-18 13:25:38 UTC
Permalink
Giacomino wrote:
[...]
Post by Giacomino
Nonostante questo il concetto di interfaccia (mediante il quale ci si
assicura che un determinato set di metodi sia presente in un oggetto)
è molto comodo e gradito.
Non sono in disaccordo, posto di non dimenticare che l'ereditarieta'
non e' l'unico modo di ottenere genericita' in C++.
Post by Giacomino
Mi sembra invece che in C++ l'eredità
multipla porta ad una duplicazione dei metodi aventi la stessa
signature presenti in sottoclassi diverse, con la necessità di dover
disambiguare. Cioè
se ho
class Base
{
virtual void methodA() { ... }
virtual void ~Base() { }
};
class Interface
{
virtual void methodA() = 0;
virtual void ~Interface() { }
};
class Derived : public Base, public virtual Interface
{ ... };
Derived* d;
...
d->methodA();
In realta' cosi' come e' scritto il tuo esempio non puo' generare
ambiguita' perche' Derived deve implementare methodA ed e' quella la
versione che sara' chiamata.

Se pero' lo riscrivi come

#include <iostream>
#include <ostream>

struct B1 {
virtual int f() { return 42; }
};

struct B2 {
virtual int f() { return 43; }
};

struct D : public B1, public B2 {
};

int main() {
D d;
std::cout << d.B2::f() << '\n';
}

devi effettivamente disambiguare.

Ciao,
Nicola
kanze
2006-10-19 14:26:57 UTC
Permalink
Giacomino wrote:

[...]
Post by Giacomino
Nonostante questo il concetto di interfaccia (mediante il quale ci si
assicura che un determinato set di metodi sia presente in un oggetto)
è molto comodo e gradito. Mi sembra invece che in C++ l'eredità
multipla porta ad una duplicazione dei metodi aventi la stessa
signature presenti in sottoclassi diverse, con la necessità di dover
disambiguare. Cioè
se ho
class Base
{
virtual void methodA() { ... }
virtual void ~Base() { }
};
class Interface
{
virtual void methodA() = 0;
virtual void ~Interface() { }
};
class Derived : public Base, public virtual Interface
{ ... };
Derived* d;
...
d->methodA();
ottengo un errore? Oppure devo disambiguare con i risolutori?
In questo punto, il C++ è più rigoroso (e più robusto) di Java.
Parte dal principio che se Base non conosce il contratto
dall'interfaccia Interface, è poco probabile che l'implementa
correttamente, anche se per caso i nomi delle funzionni son
identici. E che se Base lo conosce, questo contratto, può dirlo,
eritando di Interface. Allora, in C++:

class Interface
{
public:
virtual ~Interface() { }
virtual void methodA() = 0;
} ;

class Base : public virtual Interface
{
public:
virtual void methodA() ;
} ;

class Derived : public virtual Interface, private Base
{
} ;

E cosi, puoi scrivere:

Interface* p = new Derived ;
p->methodA() ;

Due cose importante qui: l'eritaggio virtual, che fa Java
implicitamente, se erita di una interface, e l'eritaggio privato
di Base, che non è obligato, ma che si fà in generale se Base
non è qu'un detaglia dell'implementazione.

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Giacomino
2006-10-19 15:17:26 UTC
Permalink
Post by Giacomino
class Interface
{
virtual ~Interface() { }
virtual void methodA() = 0;
} ;
class Base : public virtual Interface
{
virtual void methodA() ;
} ;
class Derived : public virtual Interface, private Base
{
} ;
Interface* p = new Derived ;
p->methodA() ;
questo va bene se devo scrivere da zero io le tre classi, ma come mi
muovo se già ho Base ed Interface, con le caratteristiche che ho
esposto prima, e devo creare una Derived?
*PaN!*
2006-10-20 17:56:33 UTC
Permalink
Post by Giacomino
questo va bene se devo scrivere da zero io le tre classi, ma come mi
muovo se già ho Base ed Interface, con le caratteristiche che ho
esposto prima, e devo creare una Derived?
a) Implementi il metodo virtuale di Interface e gli fai chiamare
esplicitamente il metodo della classe Base

b) Mandi degli sgherri a gambizzare quello che ha scritto Base, che forse
avrebbe dovuto implementare Interface o ripensare la struttura in altro modo
=)

--*PaN!*
Giacomino
2006-10-23 07:20:20 UTC
Permalink
Post by *PaN!*
a) Implementi il metodo virtuale di Interface e gli fai chiamare
esplicitamente il metodo della classe Base
come sospettavo. Non è "automatico" come in Java.
Post by *PaN!*
b) Mandi degli sgherri a gambizzare quello che ha scritto Base, che forse
avrebbe dovuto implementare Interface o ripensare la struttura in altro modo
=)
E perchè? Chi ha scritto Base potrebbe non essere a conoscenza di
Interface.
Nicola Musatti
2006-10-23 08:21:33 UTC
Permalink
Post by Giacomino
Post by *PaN!*
a) Implementi il metodo virtuale di Interface e gli fai chiamare
esplicitamente il metodo della classe Base
come sospettavo. Non è "automatico" come in Java.
Corretto.
Post by Giacomino
Post by *PaN!*
b) Mandi degli sgherri a gambizzare quello che ha scritto Base, che forse
avrebbe dovuto implementare Interface o ripensare la struttura in altro modo
=)
E perchè? Chi ha scritto Base potrebbe non essere a conoscenza di
Interface.
E proprio per questo e' quanto meno discutibile che Base possa
implementare Interface "per caso".

Ciao,
Nicola
Giacomino
2006-10-23 09:29:33 UTC
Permalink
Quindi (e scusate se insisto) se ho

class Base
{
public:
virtual int value() { return 100; }
virtual ~Base() { }
};

class Interface
{
public:
virtual int value() = 0;
virtual ~Interface() = 0;
}

class DerivedA : public Base, public virtual Interface
{
public:
virtual ~DerivedA() { }
}

DerivedA non è istanziabile perchè deve implementare
Interface::value() ?

Mentre se scrivo

class DerivedB : public Base, public virtual Interface
{
public:
virtual int value() { return Base::value(); }
virtual ~DerivedB() { }
}

tutto ok, ed ottengo lo stesso comportamento di Java?
Se si, non mi sembra "efficiente" in quanto introduco un ulteriore
chiamata, non credete? Non c'è un modo alternativo più efficiente?
Quali sono i metodi che posso chiamare da un istanza di DerivedB?

Scusate ancora se insisto anche sulle cose più banali, ma ho iniziato
con Java la OO e vorrei imparare il C++. Grazie mille per l'attenzione
e la pazienza.
Post by Nicola Musatti
Post by Giacomino
Post by *PaN!*
a) Implementi il metodo virtuale di Interface e gli fai chiamare
esplicitamente il metodo della classe Base
come sospettavo. Non è "automatico" come in Java.
Corretto.
Post by Giacomino
Post by *PaN!*
b) Mandi degli sgherri a gambizzare quello che ha scritto Base, che forse
avrebbe dovuto implementare Interface o ripensare la struttura in altro modo
=)
E perchè? Chi ha scritto Base potrebbe non essere a conoscenza di
Interface.
E proprio per questo e' quanto meno discutibile che Base possa
implementare Interface "per caso".
Ciao,
Nicola
Kiuhnm
2006-10-23 09:50:51 UTC
Permalink
Post by Giacomino
Se si, non mi sembra "efficiente" in quanto introduco un ulteriore
chiamata, non credete? Non c'è un modo alternativo più efficiente?
Lascia perdere l'efficienza. Cerca piuttosto di rendere la gerarchia di
classi la più naturale e limpida possibile.
Più avanti penserai all'efficienza.

Kiuhnm
kanze
2006-10-23 12:09:10 UTC
Permalink
Post by Kiuhnm
Post by Giacomino
Se si, non mi sembra "efficiente" in quanto introduco un ulteriore
chiamata, non credete? Non c'è un modo alternativo più efficiente?
Lascia perdere l'efficienza.
Mai. L'efficienza è tutto. Sono paggato per creare applicazioni
che funzionne, e più son'efficiente, meno costa al cuì mi paga.
Se utilisa il C++, piùtosto di Java, è solo perche sono più
efficiente in C++; ho bisogna di meno efforto (dunque, meno
tempo) in C++ che in Java per produrre una applicazione
corretta.
Post by Kiuhnm
Cerca piuttosto di rendere la gerarchia di classi la più
naturale e limpida possibile.
Cosa chi è essentiale se vuoi essere efficente.

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Kiuhnm
2006-10-24 17:36:00 UTC
Permalink
Post by kanze
Mai. L'efficienza è tutto.
All'efficienza penso in seguito. Se il programma è ben strutturato, c'è
largo spazio per l'ottimizzazione.

Kiuhnm
Kiuhnm
2006-10-24 18:26:17 UTC
Permalink
Post by Kiuhnm
All'efficienza penso in seguito. Se il programma è ben strutturato, c'è
largo spazio per l'ottimizzazione.
Uno dei punti del sistema di sviluppo IID (iterative and incremental
development), il quale ha dato buoni risultati in questi ultimi 50 anni,
dice:

"Do not optimize during the development process. That is, do not make
the design more complex just to increase performance. Use simple
algorithms with acceptable complexity and keep a simple design with the
right abstractions. Do not worry about the overhead of these
abstractions. Performance optimization can be done near the end of
development, but only if there are performance problems. Profiling
should then be used to find those parts of the system (usually very
small) that should be rewritten."

Kiuhnm
Enrico 'Mc Osten' Franchi
2006-10-25 14:45:02 UTC
Permalink
Post by Kiuhnm
Uno dei punti del sistema di sviluppo IID (iterative and incremental
development), il quale ha dato buoni risultati in questi ultimi 50 anni,
+1

Oltrechè anche un qualunque extreme programmer non potrebbe che quotare:
fai le cose fatte bene, ben strutturate. Poi se non sono veloci
abbastanza, velocizza.

Altrimenti si rischia solo di fare un sistema inutilmente veloce: dove
l'inutilmente significa che per farlo veloce si è persa manutensibilità
richiesta (e quindi utile).

Poi chiaro, ci sono campi in cui la velocità è tutto (e magari il
programma ha una struttura relativamente facile).
--
blog: http://www.akropolix.net/rik0/blogs | Uccidete i filosofi,
site: http://www.akropolix.net/rik0/ | tenetevi riso e
forum: http://www.akropolix.net/forum/ | bacchette per voi.
James Kanze
2006-10-26 17:13:15 UTC
Permalink
Post by Kiuhnm
Post by Kiuhnm
All'efficienza penso in seguito. Se il programma è ben strutturato, c'è
largo spazio per l'ottimizzazione.
Uno dei punti del sistema di sviluppo IID (iterative and incremental
development), il quale ha dato buoni risultati in questi ultimi 50 anni,
"Do not optimize during the development process. That is, do not make
the design more complex just to increase performance. Use simple
algorithms with acceptable complexity and keep a simple design with the
right abstractions. Do not worry about the overhead of these
abstractions. Performance optimization can be done near the end of
development, but only if there are performance problems. Profiling
should then be used to find those parts of the system (usually very
small) that should be rewritten."
Ci son eccezioni: se so che ci son millioni di date, non mi
servo di un'algorithmo O(n^2), neanche nel svilupemente. Ma in
generale: più l'encapsulation (scussi, ma non conosco la parole
italiana) è bene, più è facile ottimizzare quando bisogna.

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Kiuhnm
2006-10-26 17:33:34 UTC
Permalink
Post by James Kanze
Ci son eccezioni: se so che ci son millioni di date, non mi
servo di un'algorithmo O(n^2), neanche nel svilupemente.
"Use simple algorithms with *acceptable* complexity [...]"

Solo tu puoi decidere cosa è accettabile e cosa non lo è. Quella
"regola" non cerca di sostituirsi al tuo buon senso.

Kiuhnm

James Kanze
2006-10-26 17:10:29 UTC
Permalink
Post by Kiuhnm
Post by kanze
Mai. L'efficienza è tutto.
All'efficienza penso in seguito.
All'efficienza, io penso in primo. L'efficienza dal
programmatore, naturalemente. E la sola che importa.
Post by Kiuhnm
Se il programma è ben strutturato, c'è largo spazio per
l'ottimizzazione.
L'ottimizzazione serva solo per risolvere problemi di
performance. Non sono frequenti: molti programmi son abbastanza
veloce senza ottimizzazione. È propio non è efficiente pensare
alla performance se non c'è bisogna.

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nicola Musatti
2006-10-23 11:56:31 UTC
Permalink
Post by Giacomino
Quindi (e scusate se insisto) se ho
class Base
{
virtual int value() { return 100; }
virtual ~Base() { }
};
class Interface
{
virtual int value() = 0;
virtual ~Interface() = 0;
}
class DerivedA : public Base, public virtual Interface
{
virtual ~DerivedA() { }
}
DerivedA non è istanziabile perchè deve implementare
Interface::value() ?
Esatto.
Post by Giacomino
Mentre se scrivo
class DerivedB : public Base, public virtual Interface
{
virtual int value() { return Base::value(); }
virtual ~DerivedB() { }
}
tutto ok, ed ottengo lo stesso comportamento di Java?
Se si, non mi sembra "efficiente" in quanto introduco un ulteriore
chiamata, non credete? Non c'è un modo alternativo più efficiente?
Quali sono i metodi che posso chiamare da un istanza di DerivedB?
L'alternativa te l'ha mostrata James: basta scrivere

class Base : public virtual Interface
{
public:
virtual int value() { return 100; }
virtual ~Base() { }
};

Il C++ mi pare piu' coerente; vuoi un linguaggio typesafe o no? Se si,
i casi sono due: o Base implementa Interface e bisogna dichiararlo,
oppure non la implementa e bisogna delegare esplicitamente. Altrimenti
perche' richiedere l'uso delle interfacce? Tanto vale affidarsi
completamente al cosiddetto "duck typing".

Ciao,
Nicola
kanze
2006-10-23 12:04:23 UTC
Permalink
Post by Giacomino
Quindi (e scusate se insisto) se ho
class Base
{
virtual int value() { return 100; }
virtual ~Base() { }
};
class Interface
{
virtual int value() = 0;
virtual ~Interface() = 0;
}
class DerivedA : public Base, public virtual Interface
{
virtual ~DerivedA() { }
}
DerivedA non è istanziabile perchè deve implementare
Interface::value() ?
Certo. Non vado come potrei fare l'orientazion oggetto rigorosa
altremente.
Post by Giacomino
Mentre se scrivo
class DerivedB : public Base, public virtual Interface
{
virtual int value() { return Base::value(); }
virtual ~DerivedB() { }
}
tutto ok, ed ottengo lo stesso comportamento di Java?
Essattamente come in Java.
Post by Giacomino
Se si, non mi sembra "efficiente" in quanto introduco un
ulteriore chiamata, non credete?
Sembra essentiale per evitare gli errori. In fatti, è abbastanza
raro che funzionna cosi, per caso; quasi sempre si vuol
un'adattazione piu o meno complicata.
Post by Giacomino
Non c'è un modo alternativo più efficiente?
Cosa vuol dire qui, efficiente? Anche in Java, bisogna un po di
rifflessione, se va o non. E documentazione, se va. Solo, in
Java, e troppo facile a dimenticare questa; in C++, la
rifflessione et la documentazione prendono una forma che può
essere controllato del compilatore.
Post by Giacomino
Quali sono i metodi che posso chiamare da un istanza di DerivedB?
Tutti che ne ha. Anche quello che erita di Base.
Post by Giacomino
Scusate ancora se insisto anche sulle cose più banali, ma ho
iniziato con Java la OO e vorrei imparare il C++.
È un probleme, perche Java rende la OO rigorosa molta difficile.

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
kanze
2006-10-23 11:56:06 UTC
Permalink
Post by Giacomino
Post by Giacomino
class Interface
{
virtual ~Interface() { }
virtual void methodA() = 0;
} ;
class Base : public virtual Interface
{
virtual void methodA() ;
} ;
class Derived : public virtual Interface, private Base
{
} ;
Interface* p = new Derived ;
p->methodA() ;
questo va bene se devo scrivere da zero io le tre classi, ma
come mi muovo se già ho Base ed Interface, con le
caratteristiche che ho esposto prima, e devo creare una
Derived?
La prema domanda allora è, cosa ti fa pensare che Base::methodA
implementa il contrato di Interface. Se l'autore di Base
conosceve il contrato di Interface, e voleva implementarlo,
n'avrebbe derivato. Se non l'ha fatto, è poco probabile che
sarebbe conformo al contratto per caso, non?

Se veramente sei caduto sul caso eccezionnale, e sia 100% sicuro
que Base::methodA convienne, puoi prenderne la risponsibilità,
scrivendo una funzione di Derived:

virtual void
Derived::methodA()
{
Base::methodA() ;
}

Ma in questo caso, sei tu chi n'è risponabile, e non il autore
die Base. (Nella pratica, non ho mai visto che va cosi. Si vuol
quasi sempre un po de trattamento di più in Derived, alfine
d'adattare la funzione di Base al contratto di Interface.)

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
kanze
2006-10-19 14:15:49 UTC
Permalink
[...]
Post by Nicola Musatti
Post by Giacomino
- è questo il modo (più) giusto per raggiungere l'obiettivo
prefissatomi?
Secondo me e' l'obiettivo prefissato che e' sbagliato: stai
cercando di ritrovare in C++ le cose che conosci in Java,
mentre faresti meglio ad imparare direttamente "usi e costumi"
del C++.
Infatti, non ha detto l'"obiettivo prefissato". Usare
un'interfaccia comme in Java non è proprio un buon obiettivo,
neanche usare un'interfaccia per usarla. Ma il concetto di
interfaccia serva molta, anche in C++, e fà ben partite degli
"usi e costumi" di C++. (Partite solo, certo.)

--
James Kanze (GABI Software) email:***@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Alberto EMME
2006-10-18 12:22:14 UTC
Permalink
Post by Giacomino
- quali sono le implicazioni in termini di performance e di spazio
occupato?
Sto studiando ora il C++ ma se vieni da Java non ti puoi preoccupare di
performances, in quanto non credo tu riuscirai a trovare un linguaggio
che possa fare peggio di Java! Basta guardare semplicemente come
gestisce i templates....

Saluti, Alberto
Enrico 'Mc Osten' Franchi
2006-10-19 07:20:29 UTC
Permalink
Post by Alberto EMME
Basta guardare semplicemente come
gestisce i templates....
Vorrai dire come *non* gestisce (in modo serio) i templates/generics. :P
Ad ogni modo quello non da problemi di velocità.

È solo un vomitino venuto male.
--
blog: http://www.akropolix.net/rik0/blogs | Uccidete i filosofi,
site: http://www.akropolix.net/rik0/ | tenetevi riso e
forum: http://www.akropolix.net/forum/ | bacchette per voi.
*PaN!*
2006-10-18 12:31:01 UTC
Permalink
Post by Giacomino
class Interface
{
virtuual void methodA() = 0;
virtual int methodB(int x, int y) = 0;
};
- è questo il modo (più) giusto per raggiungere l'obiettivo
prefissatomi?
Medio...
Post by Giacomino
- dal punto di vista sintattico, ho qualche implicazione?
Ecco, si.
Per avere un funzionamento analogo a quello di java, dovresti dichiarare
anche il distruttore come virtuale: in C++ i distruttori sono di default non
virtuali, e non imporre il distruttore virtuale sull'interfaccia puo'
risultare in un problema quando si distruggono oggetti di tipo Interface *.
Post by Giacomino
- quali sono le implicazioni in termini di performance e di spazio
occupato?
Se il confronto e' java, non mi preoccuperei delle performance ;)
Comunque, la chiamata ad una funzione virtuale e', in genere, piu' lenta
dell'equivalente non virtuale (ma di _POCO_), con la differenza che un
ottimizzatore non sempre puo' essere in grado di ottimizzarla mettendola
inline (diciamo "quasi mai").

--
*PaN!*
Continua a leggere su narkive:
Loading...