Newsgroup: it.comp.lang.c++
Titolo: derivazione privata

Salve,
Ho la necessita' di derivare privatamente da una classe,
mantenendo pero' pubblici alcuni dei suoi elementi.
Con membri dati e con metodi non ho incontrato nessun problema,
tuttavia non sono riuscito a trovare un modo per cambiare visibilita'
ad un tipo (un enum per l'esattezza).
Ho cercato nello Stroustrup ma senza successo.
Sotto c'e' un esempio di quello che vorrei fare:
Grazie in anticipo per ogni suggerimento.
/fabio
---------------------------------------------------
class A
{
 public:
    A() {}
    virtual ~A() {}
    enum MyEnum { Item1, Item2, Item3 };
    void f();
    void g();
};
class B : private A
{
   public:
      B() {}
      ~B(){}
      A::f;  // ok, rendo A::f() pubblica
      enum A::MyEnum;
      // ERRORE: use of enum `MyEnum' without previous declaration
};
main()
{
        B b;
        int e = B::Item1; // errore: Item1 non e' pubblico
        b.f();   // legittimo;
        b.g();   // errore giusto, g() e' protetto;
}
Sent via Deja.com
http://www.deja.com/

Nella classe B io userei la clausola using per introdurre un nome nel
nuovo scope.
Ovvero:
class B : private A
{
   public:
      B() {}
      ~B(){}
      using A::f;
      using A::MyEnum;
};
questo dovrebbe evitarti l'errore di uso di MyEnum prima della
dichiarazione.
Ora pero' devi notare che un enum e' un tipo un pochino particolare. Se
dichiari 
un tipo (una classe o un typedef) come nel caso 
class A {
public:
	typedef int *PINT;
	class AClass { /*...*/ }; 
};
allora li puoi "importare" nel nuovo namespace semplicemente con using:
class B : private A {
public:
      using A::PINT;
      using A::AClass;
};
ma la clausola using importa il nome. Nel caso di un enum tu hai non
solo il 
nome del tipo ma anche il nome dei valori. 
Prova a importare anche quelli.
Ovvero tornando alla tua classe originale:
class B : private A
{
   public:
      B() {}
      ~B(){}
      using A::f;
      using A::MyEnum;
      using A::Item1;
      using A::Item2;
      using A::Item3;
};
-- 
Posted from 
adsl-21-135.38-151.net24.it
 [151.38.135.21] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 Prova a importare anche quelli.
Bravissimo! Comunque il BCC55 accetta anche se si omettono tutti gli
using? E' nel giusto o no?
EMG

 using? E' nel giusto o no?
E' giusto. Gli using sono superflui se nella classe derivata non fai
overloading di funzioni o ridichiarazione di tipi definiti nella
superclasse.
Ciao,
Nicola


Purtroppo era proprio quello che volevo evitare.
Vorrei che fosse possibile aggiungere nuovi item nella classe base senza
dover necessariamente aggiornare anche la classe derivata. Ma credo che
sia impossibile...
Il problema reale a cui mi sto riferendo e' questo:
La classe base e' una classe gia' esistente in una libreria, ha certe
funzionalita' ma non garantisce una adeguata protezione del suo
contenuto. Cosi' ho pensato di estenderla derivandone una classe con
un'interfaccia piu' consistente (una specie di proxy: la nuova
interfaccia non consente di manipolare i dati della classe base in
maniera impropria).
L'enum in questione contiene i vari codici d'errore che possono essere
ritornati dai metodi della classe base, e che verranno controllati dai
client della classe derivata.
se 'd' e' un'istanza della classe derivata, vorrei che fosse possibile
avere qualcosa del genere:
   if (d.f() == Derived::Errore) ...
invece di
    if (d.f() == Base::Errore) ...
/fabio


ad un tipo (un enum per l'esattezza).
prova questo:
class Base {
	public:
		enum tipo { a,b,c };
};
class Derived: private Base {
	public:
		typedef base::tipo tipo;
};
Anto
--
Antonio Cuni, 18 anni, studente
Brainbench Certification: 
Master C++: 4.44, higher than 97% of all previous test takers.
Visual Basic 5: 3.06, higher than 77% of all previous test takers.
http://www.brainbench.com/transcript.jsp?pid=1301688

>E' giusto. Gli using sono superflui se nella classe derivata non fai
Il solito discorso di compliance. Una cosa e' lo standard e un'altra
l'implementazione dello stesso da parte di un dato compilatore.
Usare l'using per importare i vari nomi dell'enum era una soluzione
ad un problema di implementazione dello standard.
Quindi i casi sono due: o si trova un compilatore piu' compliant o si
scrive del codice che non sarebbe necessario.
Non vedo alternative.


 };
Almeno con il BCC55 questo non funziona e gli elementi di base::tipo non
vengono visti dalla classe derivata.
EMG

vengono visti dalla classe derivata.
il DJGPP lo compila regolarmente e anche gli elementi dell'enum
vengono importati; cosa dice lo standard?
