2016-09-08 6 views
2

クラス階層の異なるレベルでoperator*()(単項逆参照演算子)とoperator*(double f)(ネイティブdouble引数を持つメンバ二項乗算)の両方を上書きすることはできませんか?C++サブクラスオーバーロードされた乗算演算子がベースオーバーロードの参照外オペレータを隠す

は考えてみましょう:

// base.h: 
template<typename T> 
class base { 
    public: 
    base(T v) : m_v(v) { } 
    T& operator*() { return m_v; } 
    const T& operator*() const { return m_v; } 
    protected: 
    T m_v; 
}; 

// special.h: 
#include "base.h" 
class super_double : public base<double> { 
    public: 
    super_double (double v) : base(v) { } 
    const super_double operator* (double f) { return super_double (m_v * f); } 
}; 

メンバーのバイナリoperator*が彼らの呼び出し規則が異なるため間接参照演算子は、基本クラスから継承された隠し、なぜ私は理解していません。次のコードは、super_doubleoperator*(double f)を定義していない場合は罰金コンパイルが、それがない場合はエラーを発し:

super_double q(289.3); 
double d = *q; // Only good if super_double doesn't define operator*(double f) 

operator*の両方の形式ではなく、テンプレートベースクラスで定義されている場合はそれもいいのよ。

なぜサブクラスの 'operator*(double f)バイナリは基本クラスの単項を隠すのですかoperator*()

答えて

1

オーバーロード解決に別個の工程です。名前ルックアップは、名前付きスコープを見つけるプロセスです。 Derivedがスコープ内にある点で名前をDerived::operator*operator*を検索する手段(又はオペレータとして*の使用)を導入

は、Derived::operator*に名前を解決します。次に、Derived::operator*のいずれの過負荷が存在する場合でも、過負荷の解決が進みます。 Derivedクラスの

using Base::operator*; 

を:オーバーロードの解決はまた、あなたが書くことによってDerivedにこれらの機能を導入する必要があり、現在Base::operator*名前が付けられていた機能を、検討していると

。つまり、Derived::operator*という名前は3つの関数のすべてを参照し、オーバーロードの解決がその中から選択されます。

2

メンバーのバイナリoperator*は、彼らが同じ名前を持っているので間接参照演算子は、基本クラスから

を継承隠す理由を私は理解していません。仮説的には、C++には、演算子関数の名前検索で正しい数の引数を持つ関数しか考慮されないという規則があるかもしれませんが、そのような規則はそのままC++言語にはありません。

これは通常の方法で修正できます。using base::operator*;派生クラス定義にあります。

1

おそらくもっと良い方法は、それを曖昧さ回避するためにバイナリの友人機能として実装することです。 C++ ネームルックアップ

template<typename T> 
class base { 
    public: 
    base(T v) : m_v(v) { } 
    T& operator*() { return m_v; } 
    const T& operator*() const { return m_v; } 
    protected: 
    T m_v; 
}; 

class super_double : public base<double> { 
    public: 
    super_double (double v) : base(v) { } 
    friend const super_double operator* (const super_double& d, double f) { return super_double (d.m_v * f); } 
}; 

int main() 
{ 
    super_double q(289.3); 
    double d = *q; 
    std::cout << d <<'\n'; 
} 
関連する問題