2

これにはいくつかの重複がありますが、メンバー変数を使用してポインターを(に)格納できる理由は誰も説明していませんがFOO、ローカル変数(のコメント部分にある)で試してみると、BAR違法です。誰かがこれを説明できますか?

#include <iostream>
using namespace std;

class FOO
{
public:
 int (FOO::*fptr)(int a, int b);
 int add_stuff(int a, int b)
 {
  return a+b;
 }
 void call_adder(int a, int b)
 {  
  fptr = &FOO::add_stuff;
  cout<<(this->*fptr)(a,b)<<endl;
 }
};

class BAR
{
public:
 int add_stuff(int a, int b)
 {
  return a+b;
 }
 void call_adder(int a, int b)
 {  
  //int (BAR::*fptr)(int a, int b);
  //fptr = &BAR::add_stuff;
  //cout<<(*fptr)(a,b)<<endl;
 }
};

int main()
{
 FOO test;
 test.call_adder(10,20);
 return 0;
}
4

5 に答える 5

8

this->*どうやら、あなたはの呼び出しの意味を誤解していますFOO

this->*メンバーfptrポインタで使用する場合、その部分はのメンバーであるthis->*こととはまったく関係ありません。メンバーへのポインターを使用してメンバー関数を呼び出す場合は、演算子(または演算子)を使用する必要があり、そのメンバーへのポインターで使用する実際のオブジェクトを常に指定する必要があります。これは、呼び出し式の部分が行うことです。つまり、通話は常に次のようになりますfptrFOO->*.*this->*

(<pointer-to-object> ->* <pointer-to-member>) (<arguments>)

またはとして

(<object> .* <pointer-to-member>) (<arguments>)

通話の左側(<pointer-to-object>またはそれ<object>以上)は省略できません。

fptrつまり、メンバー変数、ローカル変数、グローバル変数、またはその他の種類の変数であるかどうかは関係ありません。コールスルーfptr常に次のようになります。

(this->*fptr)(a, b);

オブジェクトを使用して呼び出したいと仮定し*thisます。別の例として、ポインタが指す他のオブジェクトに対してそれを呼び出したい場合、pfoo呼び出しは次のようになります。

FOO *pfoo;
...
(pfoo->*fptr)(a, b);

BARクラスでは、呼び出しはローカル変数であるかのように見えるはずです(this->*fptr)(a,b)fptr

于 2010-04-30T16:12:54.710 に答える
7

メンバー関数ポインターを使用する場合は、それが作用するオブジェクトを指定する必要があります。

つまり、BAR のインスタンスへのポインターを作成し (それを と呼びましょうbar)、次のようにする必要があります。

(bar->*fptr)(a,b)

関数または BAR のインスタンスを呼び出して、次のことを行います。

(bar.*fptr)(a,b)

別の言い方をすれば:

#include <iostream>

class BAR
{
    int i;
public:
    BAR(): i(0) {};
    int AddOne() { return ++i; };
    int GetI() { return i; };
}

int main()
{
    BAR bar;
    auto fPtr = &BAR::AddOne; // This line is C++0x only (because of auto)
    std::cout << (bar.*fPtr)(); //This will print 1 to the console
    std::cout << std::endl;
    std::cout << bar.GetI(); //This will also print 1 to the console.
}
于 2010-04-30T16:03:44.153 に答える
2

変数自体の使用は違法ではないと思います。違法なのは、クラス インスタンスなしでそのメソッドを呼び出そうとすることです。

つまり、タイプの(someVar->*fptr)(a,b)whereを実際に呼び出す必要がありますsomeVarBAR*

于 2010-04-30T16:05:54.020 に答える
1

BAR::call_adder()いくつかの問題がありました。一つには、あなたはケースを混ぜていました。C ++では、大文字と小文字が区別されます。 BARbar同じではありません。次に、大文字と小文字の問題を修正した後、デカールしてポインタを正常に割り当てましたが、ポインタを介してメンバー関数を呼び出そうとする場合operator ->*は、クラスオブジェクトで使用する必要があります。これがcall_adder()修正されました

 void call_adder(int a, int b)
 {  
  int (BAR::*fptr)(int a, int b);
  fptr = &BAR::add_stuff;
  cout<<(this->*fptr)(a,b)<<endl;
 }
于 2010-04-30T16:10:59.223 に答える
0

クラスのメンバー関数を呼び出すと、関数の実行中に「this」を設定するコードがコンパイラによって生成されます。行われていない関数ポインタから呼び出す場合。それを回避する方法はありますが、動作することが「保証」されておらず、コンパイラに依存しています。注意して、起こりうる問題を知っていれば、それを行うことができます。

于 2010-04-30T16:57:33.447 に答える