有下面一段C++
代码:
#include <iostream>
class Node {
public:
int val_;
Node *left_;
Node *right_;
Node(int val) : val_(val), left_(nullptr), right_(nullptr) {}
};
int main()
{
int Node::* val = &Node::val_;
Node * Node::* left = &Node::left_;
Node * Node::* right = &Node::right_;
std::cout << val << " " << left << " " << right << std::endl;
printf("%p %p %p\n", val, left, right);
Node *root = new Node(0);
root->left_ = new Node (1);
root->right_ = new Node (2);
root->left_->left_ = new Node (3);
root->left_->left_->right_ = new Node (4);
Node *node = root->*left->*left->*right;
std::cout << node->val_ << std::endl;
return 0;
}
运算结果:
对类成员指针不了解的同学肯定一脸懵。
int Node::* val = &Node::val_;
这里的Node::*
表示val
是Node类中成员指针类型的变量,它指向int
类型的Node
类成员。这里使用Node
的val_
成员的地址初始化它。
Node * Node::* left = &Node::left_;
Node * Node::* right = &Node::right_;
同理,left
和right
都是指向Node类中Node*类型的成员的指针。这里分别使用Node
的left_
和right_
成员的地址初始化它们。
val
、left
和right
的值是类成员的偏移量,转成bool
都是true
(这点比较奇怪)。
printf("%p %p %p\n", val, left, right); // 0x0 0x8 0x10
std::cout << val << " " << left << " " << right << std::endl; // 1 1 1
类成员指针是类的静态属性,和类对象无关。
但当使用类成员指针时,需要通过对象。
使用*
操作符,可以通过类成员指针引用类成员。
Node *root = new Node(0);
// ...
Node *node = root->*left;
// 等价于
Node *node = root->left_;
因此
Node *root = new Node(0);
// ...
Node *node = root->*left->*left->*right;
// 等价于
Node *node = root->left_->left_->right_;
node
表示root
的左节点的左节点的右节点。