9

メンバーへのポインターで遊んでいて、実際にポインターの値を出力することにしました。結果は私が期待したものではありませんでした。

#include <iostream>

struct ManyIntegers {

    int a,b,c,d;
};

int main () {

    int ManyIntegers::* p;

    p = &ManyIntegers::a;
    std::cout << "p = &ManyIntegers::a = " << p << std::endl; // prints 1

    p = &ManyIntegers::b;
    std::cout << "p = &ManyIntegers::b = " << p << std::endl; // prints 1

    p = &ManyIntegers::c;
    std::cout << "p = &ManyIntegers::c = " << p << std::endl; // prints 1

    p = &ManyIntegers::d;
    std::cout << "p = &ManyIntegers::d = " << p << std::endl; // prints 1

    return 0;
}

の値がp常に 1 になるのはなぜですか? pの値は、それが指しているクラスメンバーを何らかの形で反映すべきではありませんか?

4

6 に答える 6

9

誰もが言ったように、適切な定義ostreamがありません。operator<<

これを試して:

#include <cstddef>
#include <iostream>

struct Dumper {
  unsigned char *p;
  std::size_t size;
  template<class T>
  Dumper(const T& t) : p((unsigned char*)&t), size(sizeof t) { }
  friend std::ostream& operator<<(std::ostream& os, const Dumper& d) {
    for(std::size_t i = 0; i < d.size; i++) {
      os << "0x" << std::hex << (unsigned int)d.p[i] << " ";
    }
    return os;
  }
};

#include <iostream>

struct ManyIntegers {

    int a,b,c,d;
};

int main () {

    int ManyIntegers::* p;

    p = &ManyIntegers::a;
    std::cout << "p = &ManyIntegers::a = " << Dumper(p) << "\n"; 

    p = &ManyIntegers::b;
    std::cout << "p = &ManyIntegers::b = " << Dumper(p) << "\n"; 

    p = &ManyIntegers::c;
    std::cout << "p = &ManyIntegers::c = " << Dumper(p) << "\n"; 

    p = &ManyIntegers::d;
    std::cout << "p = &ManyIntegers::d = " << Dumper(p) << "\n"; 

    return 0;
}
于 2012-08-24T13:48:19.093 に答える
7

標準の ostreamoperator<<にはメンバーへのポインターのオーバーロードがないため、ポインターは暗黙的に に変換されていboolます。

于 2012-08-24T13:35:48.117 に答える
3

p実際にはオブジェクトにオフセットが含まれています。それらを印刷するboolと、実際にオフセットが含まれているかどうかにかかわらず、暗黙の変換値 true または false がそれぞれ印刷されます。ostreamの挿入メンバーには、メンバーへのポインターのオーバーロードがないため、変換が発生します。

于 2012-08-24T13:36:51.650 に答える
2

operator<<メンバへのポインタを引数として取るオーバーロードはありません。したがって、メンバーへのポインターを出力しようとすると、引数として取るオーバーロードに渡されるものに暗黙的に変換され、対応するものを出力します。truebool1true

std::boolalphastream-manipulatorを使用すると、次trueの代わりに出力され1ます。

std::cout << std::boolalpha << "p = &ManyIntegers::a = " << p ;
           //^^^^^^^^^^^^^^

出力 ( ideoneを参照):

p = &ManyIntegers::a = true

于 2012-08-24T13:37:28.000 に答える
0

メンバーへのポインターのメモリ内表現を示す、完全に標準に準拠した実装を次に示します。

#include <iostream>
#include <iomanip>

template<int... I> struct index_tuple { using succ = index_tuple<I..., sizeof...(I)>; };
template<int I> struct indexer { using type = typename indexer<I - 1>::type::succ; };
template<> struct indexer<0> { using type = index_tuple<>; };
template<typename T> typename indexer<sizeof(T)>::type index(const T &) { return {}; }

template<typename T> class dumper {
    unsigned char buf[sizeof(T)];
    friend std::ostream &operator<<(std::ostream &os, const dumper &o) {
        std::ios_base::fmtflags flags{os.flags()};
        std::copy_n(o.buf, sizeof(T),
            std::ostream_iterator<int>(os << std::hex << std::showbase, " "));
        return os << std::setiosflags(flags);
    }
    template<int... I> dumper (const T &t, index_tuple<I...>):
        buf{reinterpret_cast<const unsigned char *>(&t)[I]...} {}
public:
    dumper(const T &t): dumper(t, index(t)) {}
};
template<typename T> dumper<T> dump(const T &t) { return {t}; }

struct ManyIntegers {
    int a,b,c,d;
};

int main () {
    std::cout << "p = &ManyIntegers::a = " << dump(&ManyIntegers::a) << std::endl;
    std::cout << "p = &ManyIntegers::b = " << dump(&ManyIntegers::b) << std::endl;
    std::cout << "p = &ManyIntegers::c = " << dump(&ManyIntegers::c) << std::endl;
    std::cout << "p = &ManyIntegers::d = " << dump(&ManyIntegers::d) << std::endl;
}

出力は期待どおりです。

p = &ManyIntegers::a = 0 0 0 0 
p = &ManyIntegers::b = 0x4 0 0 0 
p = &ManyIntegers::c = 0x8 0 0 0 
p = &ManyIntegers::d = 0xc 0 0 0 
于 2012-08-24T14:44:23.347 に答える
0

メンバー ポインターは必ずしも数値であるとは限りません。多くの場合、構造体などになります。メンバーポインターから値を取得する方法はないと思いますが、あったとしてもそれがどのように役立つかわかりません。

于 2012-08-24T13:46:44.867 に答える