ホームページ > バックエンド開発 > C++ > クラス テンプレートを継承すると、基本クラスのパブリック メンバーが非表示になるのはなぜですか?この問題の解決策は何ですか?

クラス テンプレートを継承すると、基本クラスのパブリック メンバーが非表示になるのはなぜですか?この問題の解決策は何ですか?

Susan Sarandon
リリース: 2024-11-02 15:13:30
オリジナル
333 人が閲覧しました

Why do public members of a base class become invisible when inheriting a class template, and what are the solutions to this problem?

継承されたクラス テンプレートでのパブリック メンバーの非表示とコードの肥大化の回避

オブジェクト指向プログラミングは、保護されたクラス メンバーとパブリック クラス メンバーの継承に依存します。テンプレート化されていない環境では、この継承は簡単です。ただし、クラス テンプレートを導入すると、基本的な問題が発生します。基本クラスのパブリック メンバーが派生クラス テンプレートから見えなくなります。

問題

次の例を考えてみましょう。 :

<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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート