7

目標は、メンバー変数がクラスの初期化時_AddValueに関数を指すようにすることです。最初の の呼び出しの後、それ以降のすべての呼び出しで が呼び出されます。CreateFirstValueAddValueCreateAnotherValue

以前は、AddValueどの関数を呼び出すかを決定するための条件付きチェックを備えた 1 つの関数しかありませんでした。ifただし、そのチェックは毎回発生し、ここでは関数ポインターが有益であるように思われるため、実装に欠陥があるように感じます。

例:

class Foo
{
 private:
  int _value;
  void (*_AddValue)(int value); // Pointer to function member variable

  void CreateFirstValue(int value)
  {
    _value = value;
    _AddValue = &CreateAnotherValue;
  }

  void CreateAnotherValue(int value)
  {
    // This function will create values differently.
    _value = ...;
  }

 public:
  // Constructor
  Foo()
   : _value(0), _AddValue(CreateFirstValue)
  {
  }

  AddValue(int value) // This function is called by the user.
  {
    _AddValue(value);
  }
};

上記のコードは実際のコードではなく、私が達成しようとしていることの単なる例です。

今、私はエラーが発生しています:argument of type void (BTree::)(int) does not match void (*)(int)

4

2 に答える 2

15
&CreateAnotherValue

この構文は無効です。メンバーへのポインタを作成するには、他のメンバーの内部からでも、クラスに名前を付ける必要があります。試す

&Foo::CreateAnotherValue

この場合、修飾された非静的メンバー関数のアドレスについて話していることになります。これは許可されており、修飾されていないメンバー関数のアドレスに関するエラーを防ぎます。

もちろん、メンバーへのポインタを格納するために適切に型指定された変数が必要です。正しい宣言については、Boの回答を参照してください。それを呼び出すときが来たら、メンバーへのポインター逆参照演算子(またはのいずれ.*->*)を使用する必要があるので、次のように言います。

(this->*_AddValue)(whatever);

同じルールがデータにも適用されます。と言うと&Foo::_value、タイプのメンバーへのポインタを取得しますint Foo::*。ただし、データの場合、修飾されていない名前も受け入れられますが、動作は大きく異なります。 インスタンス内の特定のメンバー変数のアドレスである&_value、通常のポインター、タイプを提供します。int*_valuethis

于 2012-06-15T20:02:31.703 に答える
7

  void (*_AddValue)(整数値); // 関数メンバ変数へのポインタ

これは実際にはメンバーへのポインターではなく、フリー関数へのポインターです。

これを作る必要があります

void (Foo::*_AddValue)(int value); // Pointer to function member variable
于 2012-06-15T19:55:42.993 に答える