2011-08-15 5 views
4

私の目標は、C#のようなC++のようなプロパティを作成することでした。 Propertyのオブジェクトは、propとそのset/getメソッドのマスターを参照します。C++テンプレートのメンバに基づくプロパティの実現に伴ういくつかの問題

実現、Property.hの内容:

#include <iostream> 

using namespace std; 

namespace First { 

    template <class Master, class Type> 
    struct Property 
    { 
     Master &master; 

     const Type (Master::*&get)() const; 
     Type (Master::*&set)(Type value); 

     Property 
     (
      Master &master, 
      const Type (Master::*get)() const, 
      Type (Master::*set)(Type value) 
     ): 
      get(get), 
      set(set), 
      master(master) 
     { } 

     operator const Type() const { cout << "inside" << endl; return (master.*get)(); } 

     Type operator = (Type value) 
     { 
      return (master.*set)(value); 
     } 
    }; 

    // Test chamber. 
    class R 
    { 
     float x; 
     const float getx() const { cout << "returning " << 0 << endl; return 0; } 
     float setx(float value) { cout << "setting " << value << " in place of " << x << endl; return x = value; } 
    public: 
     Property<R, float> X; 

     R(): X(*this, &R::getx, &R::setx) { } 
    }; 

} 

私も作成.cppファイル:

#include "Property.h" 

using namespace First; 

int main() 
{ 
    R r; 

    r.X = 10; 

    float y = r.X; 

} 

プログラムは '0〜10の設定' をステップ、印刷 "を割り当てる" になりますが、 segfaultsは、 "R" getx()の中でどのようなコード(あるいはまったく何の違いもない)を取得するステップを呼び出すときに呼び出されます。

~/Sources$ ./a.out   

setting 10 in place of 0 
inside 
zsh: segmentation fault ./a.out 

(master。* get())の呼び出し自体が失敗するようです。このコードで何が間違っていますか?

UPD:マスターの関数呼び出しがsegfaultにつながることをテストしました.1回の(master。* set)呼び出しだけが成功しました。この呼び出しは、オブジェクトの状態、メンバーからPTR、プロパティ自体、または月面を無効にしているようです。

+0

(定着後)あなたは既に正しい答えを与えてきました。また、 'Property :: master'を参照ではなくポインタにすることをお勧めします。そうでなければ' Property'はそれを使っているクラスと同じようにコピーできません。 –

+0

@ ZeroArcan:いいえ '(master。* set)(value)'の呼び出しも問題です。不都合なことに、あなたが問題を見ることができないということだけです。 – Nawaz

+0

@ニコラ:マスターが参照またはポインタであるときはコピーできません - 有効な効果を得るには、オブジェクトを含むコピーctorを上書きする必要があります。 – ZeroArcan

答えて

6
const Type (Master::*&get)() const; 
Type (Master::*&set)(Type value); 

上記定義から&を削除してください。 &のために、これらのそれぞれは、コンストラクタが戻った後に存在しないコンストラクタパラメータにバインドされます。

はまた、​​作品、そのあなたが不運だからと思われることに注意してください。実際には未定義の動作が発生します。しかし、あなたはすぐに(master.*get)()が失敗したときの問題を知るようになり、segfaultを与えてくれて幸運です。

使用:それはかなりのパラメータを参照するよりも、初期化リスト内のアドレスのをコピーを引き起こすよう

const Type (Master::*get)() const; 
Type (Master::*set)(Type value); 

それは、何の問題もなく、今動作するはずです!

+0

それは動作します!しかし、私はまだなぜそれを理解していない。 – ZeroArcan

+0

@ ZeroArcan:C++ *で*の参照が何を意味するのか知っていますか? – Nawaz

+0

他の名前。私は今理解した。 – ZeroArcan

関連する問題