2010-09-22 11 views
5

sto lavorando sull'implementazione di una classe di fabbrica sulla falsariga di ciò che viene proposto in questa risposta ad una domanda precedente:con parametri di fabbrica e di prodotti classi che non è possibile creare un'istanza senza la fabbrica

Factory method implementation - C++

E 'una Fabbrica che memorizza una mappa dalle stringhe alle funzioni di creazione dell'oggetto in modo da poter richiedere diversi tipi di oggetti dalla fabbrica mediante un identificatore di stringa. Tutte le classi prodotte dalla fabbrica erediteranno da una classe astratta (Connection) che fornisce un'interfaccia comune per connessioni su diversi protocolli (HTTPConnection, FTPConnection, ecc ...)

Ho una buona conoscenza di come il metodo collegato a sopra funziona e ha funzionato.

Dove sto riscontrando problemi sta cercando di capire un meccanismo per impedire l'istanziazione degli oggetti Connection senza utilizzare Factory. Per fare in modo che Factory funzioni, ho bisogno di fornirgli una funzione di creazione dell'oggetto da archiviare nella sua mappa. Non posso fornirgli il costruttore perché non puoi creare dei puntatori di funzione ai costruttori. Quindi, come nel link sopra, ci deve essere una funzione di creazione dell'oggetto separata per restituire nuovi oggetti. Ma per fare ciò, ho bisogno di fare in modo che questa funzione di creazione sia un metodo statico della classe, a cui il codice client sarebbe in grado di accedere, o una funzione separata che richiederebbe a) che il costruttore delle classi Connection sia pubblico, oppure b) rendere privato il costruttore e rendere una funzione di creazione di un membro non della classe come amico, che non è ereditata e non può essere applicata dalla classe base astratta.

Analogamente, se avessi appena creato gli amici della classe Factory con le classi Connection che avrebbe dovuto produrre in modo che potessero accedere ai loro costruttori privati, funzionerebbe, ma non potrei far rispettare la classe base abstact perché gli amici non sono " t ereditato. Ogni sottoclasse dovrebbe essere esplicitamente amico della fabbrica.

Qualcuno può suggerire un metodo per implementare ciò che ho descritto sopra?

per ribadire l'requisiti:

1 - fabbrica che produce una varietà di oggetti tutti derivati ​​dalla stessa classe di base sulla base di passata identificativo per metodo Create della fabbrica.

2 - Tutte le sottoclassi che la fabbrica avrà bisogno di produrre registrerà automaticamente una funzione di creazione e di identificazione con la fabbrica (vedi collegati in modo rispondere sopra)

3 - Tutte le sottoclassi che la fabbrica produrrà non dovrebbe essere istantaneo (istantaneo?) senza passare per la fabbrica

4 - Applicare esplicitamente # 3 come parte della classe di base astratta utilizzando l'ereditarietà. Rimuovi la possibilità per qualcuno di sottoclasse dalla classe base astratta mentre fornisce anche meccanismi per istanziare liberamente gli oggetti.

L'obiettivo generale di ciò che sto cercando di ottenere è quello di consentire l'aggiunta di nuovi tipi di connessione alla gerarchia senza dover modificare la classe Factory in alcun modo, forzando anche tutte le sottoclassi di Connection a non essere istantanee direttamente dal codice cliente.

Sono aperto alla possibilità che questo non sia il modo migliore per ottenere ciò che voglio, e suggerimenti di altre alternative sono i benvenuti.

MODIFICA - Aggiungerò alcuni frammenti di codice a questo quando torno a casa per renderlo più chiaro.

risposta

1

Se ho capito bene, penso che si possa inserire un po 'di quello che si desidera nella macro METADECL che ho menzionato nella mia risposta a cui si collega, vale a dire definire una funzione statica di creatore che è un amico o dichiararla come metodo statico. Ciò consentirà di limitare il costruttore dall'uso pubblico ecc.

Di seguito provo a indicare dove deve essere lo METADECL (e METAIMPL). Lascio per voi per implementare quello che ti serve lì (io credo in te)

file di intestazione

class MySubClass : public FactoryObjectsRoot { 
    METADECL(MySubClass) // Declare necessary factory construct 
    : 
    : 
}; 

file di origine

METAIMPL(MySubClass) // Implement and bootstrap factory construct 
+0

Quindi per tutte le sottoclassi che la mia fabbrica produrrà, ho rendere privato il costruttore (per limitare la costruzione degli oggetti). Quindi da lì aggiungo una funzione di membro non membro, amico che crea nuovi oggetti o una funzione di membro statico privato in ciascuna sottoclasse (e rende ogni sottoclasse amici con la Factory in modo che possa chiamare la funzione statica privata)? Sono con te fino a qui. Ciò a cui sto combattendo è un modo per forzare in qualche modo questa sottoclasse per tutte le sottoclassi, senza richiedere che ciascuna sottoclasse definisca esplicitamente la relazione di amicizia. Idealmente, vorrei ereditare le basi di amicizia – MTLPhil

+0

(continua) che non è possibile in C++, come ho capito. Né è un puro costruttore virtuale virtuale nella classe base che imporrebbe che tutte le sottoclassi abbiano anche costruttori privati. – MTLPhil

+0

Ad esempio, nella risposta nella domanda collegata sopra non è possibile che il codice client chiami semplicemente la funzione _name * create_ ## _name() e elimini del tutto la Factory? – MTLPhil