2010-07-22 24 views
5

Perché dovrei voler definire un'interfaccia C++ che contenga metodi privati?Metodo privato in un'interfaccia C++?

Anche nel caso in cui i metodi in ambito pubblico supporteranno tecnicamente di comportarsi come metodi modello che utilizzano i metodi privati ​​sull'implementazione dell'interfaccia, anche così, stiamo dicendo le specifiche tecniche. direttamente dall'interfaccia.

Non è questa una deviazione dall'uso originale di un'interfaccia, vale a dire un contratto pubblico tra l'esterno e l'interno?

Si potrebbe anche definire una classe di amici, che utilizzerà alcuni metodi privati ​​della nostra classe, e quindi forzare l'implementazione attraverso l'interfaccia. Questo potrebbe essere un argomento.

Quali altri argomenti servono per definire metodi privati ​​all'interno di un'interfaccia in C++?

+1

! = Membri pubblici. La tua interfaccia è la tua _documentation_, non il tuo file di intestazione. –

risposta

6

La vista comune OO è che un'interfaccia stabilisce un unico contratto che definisce come oggetti conformi a tale interfaccia vengono utilizzati e come si comportano. L'idioma o il motivo NVI, non so mai quando uno diventa l'altro, propone un cambiamento di quella mentalità dividendo l'interfaccia in due contratti separati:

  • come l'interfaccia è da utilizzare
  • quali classi derivate devono offrire

Questo è in qualche modo particolare C++ (infatti qualsiasi lingua con ereditarietà multipla), dove l'interfaccia può infatti contenere codice che si adatta dall'interfaccia esterna --Come utenti vedono me-- e l'interfaccia interna - come sono implementato.

Questo può essere utile in diversi casi, in primo luogo quando il comportamento è comune ma può essere parametrizzato solo in modi specifici, con uno scheletro di algoritmo comune. Quindi l'algoritmo può essere implementato nella classe base e nei punti di estensione negli elementi derivati. Nelle lingue senza ereditarietà multipla, questo deve essere implementato dividendo in una classe che implementa l'algoritmo basato su alcuni parametri conformi ad una diversa interfaccia 'privata'. Sto usando qui 'privato' nel senso che solo la tua classe userà quell'interfaccia.

Il secondo uso comune è che utilizzando il linguaggio NVI, è semplice strumento del codice da modificare solo a livello di base:

class Base { 
public: 
    void foo() { 
     foo_impl(); 
    } 
private: 
    virtual void foo_impl() = 0; 
}; 

Il costo aggiuntivo di dover scrivere dispatcher foo() { foo_impl(); } è piuttosto piccolo e consente di aggiungere in seguito un meccanismo di blocco se si converte il codice in un'applicazione multithread, si aggiunge la registrazione a ciascuna chiamata o un timer per verificare la quantità di implementazioni diverse in ciascuna funzione ... Poiché il metodo effettivo implementato nelle classi derivate è privato a questo livello, è garantito che tutte le chiamate polimorfiche possono essere strumentate in un singolo punto: la base (questo non blocca le classi estendibili da rendendo foo_impl pensiero pubblico)

void Base::foo() { 
    scoped_log log("calling foo"); // we can add traces 
    lock l(mutex);     // thread safety 
    foo_impl(); 
} 

Se i metodi virtuali erano pubbliche, quindi non si poteva intercettare tutte le chiamate ai metodi e sarà necessario aggiungere che la registrazione e filo di sicurezza per tutti le classi derivate che implementano l'interfaccia .

3

È possibile dichiarare un metodo virtuale privato il cui scopo deve essere derivato. Esempio:

class CharacterDrawer { 
public: 
    virtual ~CharacterDrawer() = 0; 

    // draws the character after calling getPosition(), getAnimation(), etc. 
    void draw(GraphicsContext&); 

    // other methods 
    void setLightPosition(const Vector&); 

    enum Animation { 
     ... 
    }; 

private: 
    virtual Vector getPosition() = 0; 
    virtual Quaternion getRotation() = 0; 
    virtual Animation getAnimation() = 0; 
    virtual float getAnimationPercent() = 0; 
}; 

Tale scopo può fornire disegno utilità per un personaggio, ma deve essere stato derivato da un oggetto che fornisce il movimento, manipolazione animazione, ecc

Il vantaggio di fare simili anziché provinding " setPosition "," setAnimation ", ecc. è che non è necessario" spingere "il valore su ciascun frame, invece" lo si "tira".

Penso che questo possa essere considerato un'interfaccia poiché questi metodi non hanno nulla a che fare con l'effettiva implementazione di tutte le cose relative al disegno.

0

In un'implementazione del metodo modello, può essere utilizzato per aggiungere un vincolo di specializzazione: non è possibile chiamare il metodo virtuale della classe base dalla classe derivata (altrimenti, il metodo sarebbe dichiarato protetto nella classe base):

class Base 
{ 
private: 
    virtual void V() { /*some logic here, not accessible directly from Derived*/} 
}; 

class Derived: public Base 
{ 
private: 
    virtual void V() 
    { 
     Base::V(); // Not allowed: Base::V is not visible from Derived 
    } 
}; 
3

Perché dovrei voler definire un'interfaccia C++ che contiene private metodi?

La questione è un po 'ambigua/contraddittoria: se si definisce (puramente) un'interfaccia, questo significa che si definisce il pubblico l'accesso di tutto ciò che si collega ad esso. In questo senso, non si definisce un'interfaccia che contiene metodi privati.

Penso che la tua domanda derivi dalla confusione di una classe base astratta con un'interfaccia (correggimi se ho torto).

Una classe base astratta può essere un'implementazione di funzionalità parziale (o addirittura completa), che ha almeno un membro astratto. In questo caso, ha molto senso avere membri privati ​​come fa per qualsiasi altra classe.

In pratica raramente è necessario disporre di classi di base virtuali pure prive di implementazione (ovvero classi di base che definiscono solo un elenco di funzioni virtuali pure e nient'altro). Un caso in cui è richiesto è la programmazione COM/DCOM/XPCOM (e ce ne sono altri). Nella maggior parte dei casi però ha senso aggiungere alcune implementazioni private alla classe base astratta.

interfaccia
Problemi correlati