4

私の目標は、クラスで値が変更されたときにイベント レシーバーを起動することです。これに対する私の解決策は、get 関数と set 関数を使用することです。ただし、値を読み取るときのパフォーマンスの問題は望ましくありません。以下のクラスで:

class Vertex {
 public:
  const double& GetX() { return _x; } // should inline automatically
  const double& GetY() { return _y; } // ' '                     ' '
  void SetX(const double& x); // complex stuff in source file
  void SetY(const double& y); // ' '                      ' '
 private:
  double _x, _y;
}

ゲッターの定義をヘッダー ファイルに入れました。これにより、ゲッターをインライン化できるはずです。

私の質問は次のとおりです。値が変更されたときに、ヘッダー ファイルに関数定義を含める必要がない関数を自動的に呼び出す方法はありますか? それとも、誰でもデータを読み取ることができる可視性レベルがありますが、クラス自体だけがデータを変更できますか? それとも何か他のものですか?

別の方法として update 関数を手動で呼び出す方法があることはわかっていますが、それは見苦しく見えます。

vertex.X = 5;
vertex.Update();

前もって感謝します。

編集:

これまでのところ、いくつかの素晴らしい答えを聞いています。解決策は、目的によって異なります。

  • 簡単: ゲッターとセッター。あまりきれいではありませんが。
  • クリーン: プロパティ クラス (またはプロキシ); ただし、演​​算子の実装はそれほど簡単ではありません。

しかし、効率はどうでしょうか。

以前に推測した、個別の読み取り/書き込みアクセス許可の優れたトリックを考え出しました。

class Vertex {
 public:
  Vertex(double x, double y)
      : _x(x), _y(y), X(_x), Y(_y) { } // defined here for readability
  void SetX(double x) { _x = x; update(); } // defined here for readability
  void SetY(double y) { _y = y; update(); } // update would be the callback
  const double& X, Y;
 private:
  double _x, _y;
}
4

2 に答える 2

10

探しているのがクリーンな場合は、おそらくこれを行う最もクリーンな方法は、C# のように「プロパティ」オブジェクトを使用することです。

template<typename T>
class Property {
public:
    Property(std::function<void(T)> callback) : data(), callback(callback) { }

    Property& operator=(const T& newvalue) {
        data = newvalue;
        callback(data);

        return *this;
    }

    operator T() const {
        return data;
    }

private:
    T data;
    std::function<void(T)> callback;
};

class Vertex {
public:
    Vertex() : X(&xcallback), Y(&ycallback) { }

    Property<double> X, Y;
};

(関数は、SO で簡潔にするためにインラインになっています。必要に応じて、それらを移動できます。)次に、次のことができます。

Vertex v;

v.X = 4;
v.Y = 2.3443;

値が割り当てられるたびに、それぞれのコールバックが呼び出されます。また、 a を使用する場所の代わりにv.Xandを使用することもできるため、通常の s のように動作します ( 、などを実装する必要があるという事実を除いて)。v.Ydoubledouble-=+=

于 2012-02-04T22:01:45.267 に答える
0

時期尚早に最適化しないでください。シンプルで理解しやすい/変更しやすいコードを記述し、プロファイリングして実際にボトルネックがあることを確認してから最適化します。

get/アプローチを使用setして、メソッドでイベント ハンドラーを呼び出しますset

データの読み取りを許可するアクセス修飾子はありませんが、アクセスをクラスのみに制限します。

また、ヘッダー ファイルに関数定義を含める必要はありません。追加のジャンプ命令のコストは、99% の場合無視できます。

于 2012-02-04T21:58:31.200 に答える