typedef std::queue<int> Q
Q
是一个适配 queue
的容器。
typedef Q::container_type C
C
是 Q
的底层容器,Q
是一个使用 deque<int>
作为容器的对象。
C & get (Q &q) {
get
接收一个queue
对象并返回一个deque
对象。实际上,它返回的是queue
所包装的deque
对象,这在常规情况下是不可能的。
struct hack : private Q {
hack
是一种只在函数内部使用的类型。它继承自 Q
,仅有一个静态成员函数。从它的名称来看,您可能会怀疑它是一种黑科技。您是正确的。
永远不会实例化任何 hack
。
static C & get (Q &q) {
hack::get
的签名与 get
本身相同。实际上,我们将所有 get
的工作委托给这个方法。
return q.*&hack::c;
这一行需要拆分成多行。我会用更多的行来描述:
using mem_ptr_t = C Q::*; // aka typedef C Q::*mem_ptr_t;
mem_ptr_t c_mem_ptr = &hack::c;
C& ret = q.*c_mem_ptr;
return ret;
第一行定义了一个指向类型为
C
的字段的成员指针类型,它位于
Q
中。C++11 和 C++03 命名此类型的方式都不美观。
第二行获取了一个指向
Q
中字段
c
的成员指针。通过 C++ 类型系统中的漏洞来实现。
&hack::c
逻辑上属于类型
C hack::*
-- 即在类型为
hack
的类中,类型为
C
的成员指针。实际上,这就是我们为什么可以在
hack
的静态成员中访问它的原因。但所说的
c
实际上位于
Q
中,因此该表达式在 C++ 中的实际类型是
C Q::*
:指向
Q
类型的成员变量的指针。
你无法在
hack
中直接获取此成员指针,
&Q::c
是不合法的,但
&hack::c
不是。
您可以将成员指针视为对另一种类型的“类型化偏移量”:
&hack::c
是
c
在
Q
中的“偏移量”,同时知道它的类型是
C
。现在,这并不是真的,它只是一些不透明的值,告诉编译器如何从
Q
中获取
c
-- 但以这种方式考虑有助于理解(在简单情况下可能是这样实现的)。
然后,我们将此成员指针与
Q&
一起使用,从
Q
获取
c
。获取成员指针受到 protected 的限制:但使用它则没有!我们使用成员解引用运算符 operator
.*
,该运算符可以在左边传递类实例,在右边传递成员函数指针或成员变量指针。
instance .* member_ptr
是一个表达式,用于找到
instance
中由
member_ptr
“指向”的成员。在原始代码中,所有操作都在一行完成。
instance .* &class_name::member_name
看起来好像有一个操作符.*&
。
}
};
然后我们关闭静态方法和 hack
类,并:
return hack::get(q);
}
调用它。这种技术可以访问protected
状态:如果没有它,protected
成员只能在相同实例的子类中访问。使用它,我们可以访问任何实例的protected
成员,而不违反标准的任何部分。
.*
和&
。 - chris-->
更有趣(https://dev59.com/RXI-5IYBdhLWcg3w18d3),而且我不知道为什么会使用这种东西,+1。 - vsoftco