2012-01-12 18 views
6

私の問題は単純なものです。動的に割り当てられた型へのポインタを保持するクラステンプレートがあります。間接演算子をオーバーロードして、 - >演算子を使用してクラステンプレートインスタンスを参照するように、直接内部に含まれるポインタを使用するかのようにリダイレクトされます。C++の間接演算子のオーバーロード

instance.ptr->someMemberMethod(); 

私は単純に入力します:でも

intance->someMemberMethod(); 

MyClass<SomeObject> instance; 

それでは、私がしたいことは代わりに入力するのである:

​​

いくつかのタイプのMyClassを作成あなたはinstanceではありませんそれはポインタのように振る舞いますinstanceが含まれています。オペレータの負担をかけることによってそのギャップを埋める方法は?

+0

現代のC++デザイン(Andrei Alexandrescu)は、もっと深いことを望むなら、本当に良い情報をいくつか持っています。 –

答えて

11

あなただけoperator->operator*をオーバーロードすることができます

template<class T> 
class MyClass 
{ 
    T* ptr; 

public: 
    T* operator->() { 
     return ptr; 
    } 

    // const version, returns a pointer-to-const instead of just a pointer to 
    // enforce the idea of the logical constness of this object 
    const T* operator->() const { 
     return ptr; 
    } 

    T& operator*() { 
     return *ptr; 
    } 

    // const version, returns a const reference instead of just a reference 
    // to enforce the idea of the logical constness of this object 
    const T& operator*() const { 
     return *ptr; 
    } 
}; 

注による言語の作成者によって設計上の決定に、あなたは.演算子をオーバーロードすることができない、ということ。

また、operator*は、逆参照演算子の代わりに演算子の演算子にオーバーロードすると思われるかもしれません。しかし、これは当てはまりません。なぜなら、乗算演算子は1つの引数を取ります(逆参照演算子は引数をとりません)。このため、コンパイラはどちらがどちらであるかを判断できます。

最後に、operator->はポインタを返しますが、operator*は参照を返します。間違って混乱させるのは簡単です。

+0

良い答え。しかし、constバージョンと非constバージョンの違いを教えてください。いつ私はどちらかを使いますか? – SimpleGuy

+0

なぜ ' - >'と '*'をオーバーロードする必要があるのでしょうか? ' - >'で十分でないのはなぜですか? – SimpleGuy

+0

@SimpleGuyあなたのクラスのユーザは 'foo-> bar'が'(* foo).bar'と同等であると一般的に期待しています。彼らを異ならせることは、多くの人々に衝撃を与えるでしょう。 – Bernard

5

過負荷->オペレータ:両方オーバーロードがオブジェクトを変化させません

template <typename T> class MyClass 
{ 
    T * p; 
public: 
    T  * operator->()  { return p; } // #1 
    T const * operator->() const { return p; } 
}; 

こと。それにもかかわらず、私たちは#1非constを作ることを決めるので、私たちは尖った者へのオブジェクトの恒久性を保ちます。これは時には "深い恒常性の伝播"と呼ばれることもあります。言語Dはこれをはるかに上回ります。

+0

"私たちは#1非const"を作ることに決めました - 少なくとも、私たちが望むならば可能です。標準的なスマートポインタは、基本的に同じ理由で、 'T * const'を介して' T'型のオブジェクトを変更することはできません。あなたは、 'instance'が他のオブジェクトへの間接参照であるかどうかに依存します(標準のスマートポインタを模倣するかどうかによって決まります)。 –

+1

@SteveJessop: "私たちはすべての意見の現存する支配者"ではなく、 "あなたと私、このC++への旅にある"のように、私は思います。申し訳ありません、古い習慣:-) –

3

メンバーアクセス演算子は、アクセスするオブジェクトへのポインタを返すためにオーバーロードすることができます。

T * operator->() {return ptr;} 
T const * operator->() const {return ptr;} 

あなたはまた、それがさらにポインタのような気分にさせるために、敬意演算子をお勧めします。

T & operator*() {return *ptr;} 
T const & operator*() const {return *ptr;} 
関連する問題