Recentemente ho scoperto una nuova applicazione della parola chiave using
; non con riferimento alla funzionalità namespace
ma all'interno di una dichiarazione di classe derivata. Nel mio caso questo era pertinente per quanto riguarda i problemi che circondano la funzione membro 'operator ='.Svantaggi della parola chiave "Utilizzo" in C++ applicata alle classi derivate
ho avuto una situazione in cui, date le dichiarazioni:
class CString{
public:
...//Various functions.
operator=(const CString &cString)
{
//code to share internal array and increment reference count
}
operator=(const wchar_t *pstrString)
{
//code to create a personal internal array,
//resize it appropriately and copy the pstrString argument.
}
...
};
class CStringEx : public CString{
...//various members that expand upon CString's abilities.
};
... un oggetto di CStringEx
non ha funzionato come mi aspettavo:
CStringEx cString;
cString=L"String contents";
Invece un errore di compilazione è stato generato affermando ' CStringEx non ha una funzione 'operator =()' che accetta un argomento di tipo wchar_t * '(o - molto chiuso - parole in tal senso). Dopo un bel po 'di studio ho imparato che questo è dovuto al fatto che anche le funzioni membro generate automaticamente dal compilatore operator=
di una classe derivata sovrascrivono quelle ereditate dalla sua classe genitore. Questo sembra contro-intuitivo e user-UN amichevole per me.
Tuttavia, se aggiungo una parola chiave using
:
class CStringEx : public CString{
public:
using CString::operator=;
...
};
... il bambino della classe sarà ora utilizzare la funzione operator=
membro del suo genitore e tutto va bene.
Finora, tutto bene. Tuttavia, dopo ulteriori letture qui e altrove ho appreso che molti programmatori non amano utilizzare using
per questo scopo. Ad esempio, ho letto alcuni commentatori che descrivono effetti collaterali potenzialmente indesiderati, come il branding in TUTTO l'operatore = dal genitore. Tuttavia, ancora una volta, a parte circostanze molto specifiche, non capisco perché l'ereditarietà di tutte le funzioni dei membri del genitore sia e sia problematica. Se questa è la preoccupazione principale, qualcuno potrebbe spiegare i pericoli generali di farlo?
L'unica alternativa che posso pensare è quello di scrivere le funzioni stub nella classe bambino per ognioperator=
membro funzione del suo genitore e quindi chiamare in modo esplicito quei rispettivi Stati-funzioni:
class CStringEx : public CString{
public:
...
const CStringEx& operator=(const wchar_t* pstrString)
{
CString::operator=(pstrString);
return *this;
}
const CStringEx& operator=(const CString &cString)
{
CString::operator=(cString);
return *this;
}
...//and so on...
};
Quando rispetto alla versione con using CString::operator=
questo sembra estremamente brutto, ingombrante e disordinato per me. Quindi, ancora una volta, perché non utilizzare la parola chiave using
?
"Ho appreso che molti programmatori non amano utilizzare utilizzando per questo scopo." Senza senso. Se è lo strumento giusto, è lo strumento giusto. –
"Non capisco perché qualcuno potrebbe spiegare i pericoli di farlo?" Presumibilmente qualunque ragionamento che hai lasciato fuori dalla tua domanda potrebbe alludere a questo. –
Woah ... Questo è un po 'di ascesa rimediabile! Ma va bene; intendi il ragionamento di coloro a cui non piace usare __using__? Se è così allora, per esempio [link] http://stackoverflow.com/questions/4122214/why-operator-doesnt-get-inherited-from-a-template-class [/ link] e _David Rodríguez_ comments. Chiarire; Non capisco perché la situazione che descrive sia "cattiva" e una ragione per usare invece l'approccio alla funzione stub. Ci sono altri esempi di scoraggiamento simile per _using_ in quel post e in altri. –