我正在使用指向成员的指针,并决定实际打印指针的值。结果不是我的预期。
#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
的值不应该以某种方式反映它指向哪个类成员吗?
答案 0 :(得分: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;
}
答案 1 :(得分:7)
标准ostream operator<<
没有指向成员的指针的重载,因此指针已隐式转换为bool
。
答案 2 :(得分:3)
p
实际上包含对象中的偏移量。打印它们会打印隐式转换的bool
值true或false,如果它们分别真的包含某些偏移量。转换发生的原因是ostream
的插入成员没有指向成员的指针的重载。
答案 3 :(得分:2)
没有operator<<
的重载,它将指针指向成员作为参数。因此,如果您尝试打印指向成员的指针,则隐式地转换为true
,并将其传递给以bool
作为参数的重载,并打印1
}对应true
。
如果您使用std::boolalpha
流操作符,则会打印true
而不是1
:
std::cout << std::boolalpha << "p = &ManyIntegers::a = " << p ;
//^^^^^^^^^^^^^^
输出(见ideone):
p =&amp; ManyIntegers :: a = true
答案 4 :(得分:0)
成员指针不一定是数值,通常它是结构或类似的东西。我认为没有办法从成员指针获取值,但即使有,我也看不出它会如何有用。
答案 5 :(得分: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