2

メンバー関数に関するアドレスを把握するために、いくつかのテスト コードを作成します。しかし、結果は私を混乱させます。コードは

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

class A
{
public:
        A(char _a, char _b, char _c, char _t):a(_a), b(_b), c(_c), t(_t){}

private:
        char t;
        char a;
public:
        char b;
        char c;
        void test1(){std::cout << a << std::endl;}
        void test2(){std::cout << b << std::endl;}
        void test3(){std::cout << c << std::endl;}
        void test4(){std::cout << t << std::endl;}

        static void print(){

                char A::*pa = &A::a;
                char A::*pb = &A::b;
                char A::*pc = &A::c;
                char A::*pt = &A::t;
                printf("data member : %p, %p, %p, %p\n", pa, pb, pc, pt);

                void (A::*pf1)() = &A::test3;
                void (A::*pf2)() = &A::test2;
                void (A::*pf3)() = &A::test3;
                void (A::*pf4)() = &A::test2;
                printf("function member : %p, %p, %p, %p\n", pf1, pf2, pf3, pf4 );
        }
};

int main()
{
        A::print();

    //system("pause");//need on Dev-c++
        return 0;
}

このコードを g++ を使用した ubuntu と Dev-C++ を使用した Windos で実行しましたが、結果は同じです

data member : 0x1, 0x2, 0x3, (nil)
function member : 0x8048780, (nil), 0x804874e, (nil)

pf2 と pf4 が nil なのはなぜですか?

4

2 に答える 2

3

メンバーへのポインターは通常のポインターではありません。メンバーへのポインターのサイズと通常のポインターのサイズを出力することでテストできます。あなたが持っているコードは未定義の動作を示しますが、結果の簡単な説明が必要な場合printfは、可変数の引数を取ります。これは、引数を事前に考えられた順序でスタックにプッシュし、その数に関する追加情報を追加することによって実装されています。呼び出しの引数の数は。

あなたの場合、メンバーへのポインター関数はそのままプッシュされ(通常は通常のポインターの2倍のサイズ)、printfスタックを読み取り、そこにあるビットを通常のポインターとして解釈します。私の推測では (これを確認するには、コンパイラ/プラットフォームのドキュメントを読む必要があります)、最初の 2 つの引数のみを出力し、内容をカンマで区切って表示していると思います。

これを行うには、メンバー関数へのポインターと適切なサイズの char 配列の和集合を作成し、メンバーへのポインターで初期化し、配列を介して 16 進値を出力するのが少し良い方法です。

于 2012-08-10T03:08:20.383 に答える
2

pf2 と pf4 が nil なのはなぜですか?

示されているコードには未定義の動作があるためです。メンバー関数へのポインターはポインターではありません(はい、そうです、名前付けが悪いことはわかっています。C++ など)、printf 形式の文字列はポインターを想定しています。

于 2012-08-10T02:54:28.120 に答える