我遇到了一个包装着boost::shared_ptr
的类,并且在理解转换操作符的工作方式以及它具体如何工作方面遇到了麻烦。班级:
class TestWrapper {
public:
explicit TestWrapper(int* ptr) : internal(ptr) {}
typedef boost::shared_ptr<int> TestWrapper::* safe_bool;
boost::shared_ptr<int> internal;
bool operator!() { return !internal; }
operator safe_bool() const { return internal ? &TestWrapper::internal : 0; }
};
代码像下面的代码一样进行测试,就像它们像测试封装指针的null
一样:
TestWrapper t(new int(5));
if(!t) {
std::cout << "!null" << std::endl;
}
if(t) {
std::cout << "null" << std::endl;
}
但是,我一直无法绕过typedef的含义:
typedef boost::shared_ptr<int> TestWrapper::* safe_bool;
它看起来不像是boost::shared_ptr
的重命名,也不像是函数指针(需要括号吗?)。什么事?
我也弄不清楚转换运算符的含义:
operator safe_bool() const { return internal ? &TestWrapper::internal : 0; }
什么是&TestWrapper::internal
?为什么与typedef
是同一类型?为什么可以将0转换为它?
答案 0 :(得分:4)
boost::shared_ptr<int> TestWrapper::*
这是一个类数据成员指针。它指向类型为TestWrapper
的类boost::shared_ptr<int>
的数据成员
让我们用类数据成员指针给出一个更简单的示例:
int X::*
这是指向类int
中类型为X
的数据成员的类数据成员指针,因此您可以执行以下操作:
struct X
{
int a;
int b;
float c;
};
struct Y
{
int a;
};
auto test()
{
using T = int X::*; // a pointer to an int data member of class X
X x1{1, 2};
X x2{100, 200};
T pa = &X::a; // pointer to data member a of class X
T pb = &X::b; // pointer to data member b of class X
T pc = &X::c; // illegal
T py = &Y::a; // illegal
std::cout << x1.*pa; // 1
std::cout << x1.*pb; // 2
std::cout << x2.*pa; // 100
std::cout << x2.*pb; // 200
}
operator safe_bool() const
这是上述类数据成员指针类型的转换运算符。
什么是
&TestWrapper::internal
是类internal
的数据成员TestWrapper
的地址
为什么它与typedef类型相同
因为internal是类boost::shared_ptr<int>
的类型TestWrapper
的类数据成员
为什么0可以转换为它
作为指针,您可以为其分配nullptr
。或者,如代码所示,您可以为其分配0
。仅当internal
时,此运算符才返回指向数据成员(bool) internal != false
的指针,否则返回空指针。