継承されたクラス テンプレートでのパブリック メンバーの非表示とコードの肥大化の回避
オブジェクト指向プログラミングは、保護されたクラス メンバーとパブリック クラス メンバーの継承に依存します。テンプレート化されていない環境では、この継承は簡単です。ただし、クラス テンプレートを導入すると、基本的な問題が発生します。基本クラスのパブリック メンバーが派生クラス テンプレートから見えなくなります。
問題
次の例を考えてみましょう。 :
<code class="cpp">class CBase { public: int Fn1(void) { ... } }; class CDerived : public CBase { public: int FnSum(void) { ... CBase::Fn1(); ... } };</code>
このコードをテンプレート化すると、CBase の Fn1() メンバーが 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
この問題に対処するために、さまざまな解決策が存在します:
解決策 1 (冗長な接頭辞):
<code class="cpp">int FnSum(void) { return CBase<BYTES>::Fn1() + CBase<BYTES>::Fn2() + CBase<BYTES>::Arr[0]; }</code>
ただし、このアプローチでは、複数のメンバーを参照するときにコードが過度に肥大化します。
解決策 2 (冗長な "this->" プレフィックス):
<code class="cpp">int FnSum(void) { return this->Fn1() + this->Fn2() + this->Arr[0]; }</code>
解決策 1 と似ていますが、冗長度は若干低くなります。
解決策 3 (ステートメントの使用):
<code class="cpp">using CBase<BYTES>::Arr; using CBase<BYTES>::Fn1; using CBase<BYTES>::Fn2;</code>
これにより、追加のプレフィックスなしで CBase メンバーに直接アクセスできます。
解決策 4 (許可モード):
<code class="cpp">// Compiler flags: /permissive- (MSVC), -fpermissive (GCC/Cl), -fno-implicit-templates (Clang)</code>
厳密な C 準拠を無効にして問題は解決しますが、移植性の問題が発生する可能性があります。
より良い解決策
解決策 3 は、他のものよりもクリーンですが、依然として「using」ステートメントを繰り返す必要があります。マクロを使用すると、これを簡素化できます。
<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>
派生クラス内:
<code class="cpp">USING_CBASE(BYTES); // Makes all mentioned CBase members directly accessible</code>
このアプローチにより、コードの肥大化と重複が大幅に削減されます。
以上がクラス テンプレートを継承すると、基本クラスのパブリック メンバーが非表示になるのはなぜですか?この問題の解決策は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。