La risposta accettata lo spiega per le funzioni private virtuali , ma risponde solo a uno specifico aspetto della domanda, che è considerevolmente più limitato di quello richiesto dall'OP. Quindi, dobbiamo riformulare: Perché siamo obbligati a dichiarare le funzioni private non-virtuali nelle intestazioni?
Un'altra risposta richiama il fatto che le classi devono essere dichiarate in un blocco, dopo di che sono sigillate e non possono essere aggiunte. Questo è quello che faresti omettendo di dichiarare un metodo privato nell'intestazione, cercando quindi di definirlo altrove. Bel punto. Perché alcuni utenti della classe dovrebbero essere in grado di aumentarlo in un modo che altri utenti non possono osservare? I metodi privati ne fanno parte e non sono esclusi da questo. Ma poi chiedi a perché sono inclusi, e sembra un po 'tautologico. Perché gli utenti di classe devono sapere su di loro? Se non erano visibili, gli utenti non potevano aggiungerne nessuno, e hey presto.
Quindi, volevo fornire una risposta che, piuttosto che includere solo metodi privati per impostazione predefinita, fornisca punti specifici a favore di renderli visibili agli utenti. Un motivo meccanicistico per le funzioni private non virtuali che richiedono la dichiarazione pubblica è fornito in Herb Sutter's GotW # 100 sull'idioma Pimpl come parte di la sua logica. Non parlerò di Pimpl qui, sono sicuro che lo sappiamo tutti. Ma ecco il bit rilevante:
In C++, when anything in a header file class definition changes, all users of that class must be recompiled – even if the only change was to the private class members that the users of the class cannot even access. This is because C++’s build model is based on textual inclusion, and because C++ assumes that callers know two main things about a class that can be affected by private members:
-
Size and Layout: [of members and virtual functions - self-explanatory and great for performance, but not why we're here]
-
Functions: The calling code must be able to resolve calls to member functions of the class, including inaccessible private functions that overload with nonprivate functions — if the private function is a better match, the calling code will fail to compile. (C++ took the deliberate design decision to perform overload resolution before accessibility checking for safety reasons. For example, it was felt that changing the accessibility of a function from private to public shouldn’t change the meaning of legal calling code.)
Sutter è, ovviamente, una fonte estremamente affidabile come membro del Comitato, quindi conosce "una decisione deliberata sul design" quando ne vede uno. E l'idea di richiedere una dichiarazione pubblica di metodi privati come mezzo per evitare una semantica alterata o accessibilità accidentalmente danneggiata in seguito è probabilmente la motivazione più convincente. Per fortuna, l'intera faccenda sembrava piuttosto inutile prima d'ora!