Metodo di aggiunta c ++ alla classe definita nel file di intestazione
Domanda
Mi chiedo se sia possibile aggiungere metodi nel programma principale a una classe esistente definita nel file di intestazione.
Per esempio:
C'è class CFun
definito nel file CFun.hpp
, ma nel nostro party.cpp
vogliamo aggiungere un metodo void hello() {cout << "hello" << endl;};
senza modificare Multiple declaration for 'CFun'
Ovviamente (purtroppo) costruzione:
#include "CFun.hpp"
class CFun
{
public:
void hello() {cout << "hello" << endl;};
};
non funziona restituendo un errore <=>
È possibile farlo funzionare senza eredità di classe?
Soluzione
No, ma potresti aggiungere un metodo che accetta un riferimento / puntatore a una classe CFun - semplicemente non avrai accesso ai dati privati:
void Hello(CFun &fun)
{
cout << "hello" << endl;
}
Questo è probabilmente il migliore che sarai in grado di fare. Come sottolineato da litb - questa funzione deve essere nello stesso spazio dei nomi di CFun. Fortunatamente, gli spazi dei nomi, a differenza delle classi, possono essere aggiunti in più punti.
Altri suggerimenti
Puoi ridefinire la classe in questo modo:
#define CFun CLessFun
#include "CFun.hpp"
#undef CFun
class CFun : CLessFun
{
public:
void hello() {cout << "hello" << endl;};
};
Inseriscilo in un nuovo file di intestazione CMoreFun.hpp
e includilo invece di CFun.hpp
No, non è possibile. Può esistere una sola definizione di una determinata classe e deve essere una definizione completa, il che significa che non è possibile avere definizioni parziali in luoghi diversi, aggiungendo membri alla classe.
Se devi aggiungere una funzione membro a una classe, allora devi cambiare la definizione della classe (modifica CFun.hpp), o derivare una nuova classe da CFun
e inserire hello()
lì.
L'analogo più vicino a quel tipo di costrutto (aggiunta di funzionalità a classi predefinite) in C ++ è il modello Decorator. Non è esattamente quello che stai cercando, ma potrebbe permetterti di fare ciò di cui hai bisogno.
Questo sembra un ovvio caso d'uso per l'ereditarietà. Definisci una nuova classe:
#include "CFun.hpp"
class CFun2 : public CFun
{
public:
void hello() {cout << "hello" << endl;};
};
Quindi usa CFun2
invece di CFun
nel tuo codice sorgente.
Dopo averci pensato, potresti fare qualcosa di terribile: trova una funzione in CFun che ha il tipo di ritorno che desideri e viene menzionato una sola volta nell'intera intestazione. Diciamo void GoodBye()
.
Ora crea un file CFunWrapper.hpp con questo contenuto:
#define GoodBye() Hello() { cout << "hello" << endl; } void GoodBye()
#include "CFun.hpp"
#undef GoodBye
Quindi includi sempre e solo CFunWrapper.hpp invece di CFun.hpp.
Ma non farlo, a meno che non ci siano delle buone ragioni per farlo. È estremamente soggetto a rotture e potrebbe non essere nemmeno possibile, a seconda del contenuto di CFun.hpp.
Non a mia conoscenza. Tuttavia, potresti fare una sorta di rigging della giuria e creare una soluzione per lo spazio dei nomi.
class Party : class CFun
(your party.cpp)
eredita roba di CFun, inclusa la funzione hello ().
...
Party p;
p.hello();
No?