Vermeidung der Unsichtbarkeit öffentlicher Mitglieder und des Aufblähens von Code in geerbten Klassenvorlagen
Objektorientierte Programmierung basiert auf der Vererbung geschützter und öffentlicher Klassenmitglieder. In Umgebungen ohne Vorlagen ist diese Vererbung unkompliziert. Bei der Einführung von Klassenvorlagen tritt jedoch ein grundlegendes Problem auf: Öffentliche Mitglieder der Basisklasse werden für die abgeleitete Klassenvorlage unsichtbar.
Das Problem
Betrachten Sie das folgende Beispiel :
<code class="cpp">class CBase { public: int Fn1(void) { ... } }; class CDerived : public CBase { public: int FnSum(void) { ... CBase::Fn1(); ... } };</code>
Beim Erstellen dieses Codes verschwindet das Fn1()-Mitglied von CBase aus der Perspektive von CDerived:
<code class="cpp">template<unsigned int BYTES> class CBase { public: int Fn1(void) { ... } }; template<unsigned int BYTES> class CDerived : public CBase<BYTES> { public: int FnSum(void) { ... Fn1(); ... } // Error: Fn1 not found! };</code>
Solutions
Es gibt verschiedene Lösungen, um dieses Problem zu beheben:
Lösung 1 (Ausführliches Präfixieren):
<code class="cpp">int FnSum(void) { return CBase<BYTES>::Fn1() + CBase<BYTES>::Fn2() + CBase<BYTES>::Arr[0]; }</code>
Dieser Ansatz führt jedoch zu einer übermäßigen Codeaufblähung, wenn auf mehrere Mitglieder verwiesen wird.
Lösung 2 (Ausführliches „this->“-Präfix):
<code class="cpp">int FnSum(void) { return this->Fn1() + this->Fn2() + this->Arr[0]; }</code>
Ähnlich wie Lösung 1, aber etwas weniger ausführlich.
Lösung 3 (Anweisung verwenden):
<code class="cpp">using CBase<BYTES>::Arr; using CBase<BYTES>::Fn1; using CBase<BYTES>::Fn2;</code>
Dies ermöglicht den direkten Zugriff auf CBase-Mitglieder ohne zusätzliche Präfixe.
Lösung 4 (Permissiver Modus):
<code class="cpp">// Compiler flags: /permissive- (MSVC), -fpermissive (GCC/Cl), -fno-implicit-templates (Clang)</code>
Deaktiviert die strikte C-Konformität und löst das Problem, kann jedoch zu Portabilitätsproblemen führen.
Eine bessere Lösung
Während Lösung 3 dies ist sauberer als die anderen, erfordert es immer noch wiederholte „using“-Anweisungen. Makros können dies vereinfachen:
<code class="cpp">#include <boost/preprocessor.hpp> #define USING_ONE(r, base, member) using base::member; #define USING_ALL(base, ...) BOOST_PP_SEQ_FOR_EACH(USING_ONE, base, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) #define USING_CBASE(param) USING_ALL(CBase<param>, Arr, Fn1, Fn2, Fn3, Fn4, Fn5)</code>
In der abgeleiteten Klasse:
<code class="cpp">USING_CBASE(BYTES); // Makes all mentioned CBase members directly accessible</code>
Dieser Ansatz reduziert das Aufblähen und Duplizieren von Code erheblich.
Das obige ist der detaillierte Inhalt vonWarum werden öffentliche Mitglieder einer Basisklasse unsichtbar, wenn eine Klassenvorlage geerbt wird, und welche Lösungen gibt es für dieses Problem?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!