基本クラスと派生クラスの両方に同じデータ メンバーがあるため、多くの混乱が生じ、スコープ解決演算子を使用して競合を解決する必要があります。では、なぜ C++ で許可されているのでしょうか。誰でも私にこれの必要性を示すことができますか?
3 に答える
正確な動機はわかりませんが、それは避けられないいくつかの同様のケースの単純な拡張であると私は信じています. たとえば、多重継承を考えてみましょう。多くの基本クラスが同じメンバーを持つ可能性があり、派生クラスの作成者としてできることは基本的にありません。CRTP の場合はさらに悪いことに、基本クラスのメンバーは任意であるため、おそらく知ることはできません。これらのケースは、質問の主題よりも混乱が少ないように見え、いくつかの機能を損なうことなく単純に禁止することはできないため、はるかに問題があります. いずれにせよ曖昧性の問題に取り組まなければならないので、この特定のケースが同じ統一ルールで処理されるのは当然のことのように思えます。
影を落とすことは必ずしも悪いことではありません。シャドウイングが非常に重要な反例の 1 つは、可変個引数テンプレート (特にタプル) を扱う場合です。
例 : 次のタプルの単純化された実装を考えてみましょう。これは、可変個引数テンプレートの使用方法を見た最初の例でした。
template<typename... T> class tuple0;
template<> class tuple0<> {}; // end recursion
template<typename Head, typename... Tail>
class tuple0<Head, Tail...> : public tuple0<Tail...> {
public:
Head head;
};
ここでtuple0<int, double>
、両方の要素を作成してアクセスしたいとします。これを行うテストプログラムは次のとおりです
int main()
{
tuple0<int, double>* t1 = new tuple0<int, double>;
t1->head = 7; // set the integer value
std::cout << "integer: " << t1->head << std::endl;
tuple0<double>* t2 = static_cast< tuple0<double>* >(t1);
t2->head = std::cos(2); // set the double value
std::cout << "double: " << t2->head << std::endl;
return 0;
}
ここで、影がなければ、可変個引数テンプレートを扱うのははるかに難しいことがわかります。さらに、std::tuple の get<> メソッドにも同様の実装があります。