I am currently writing a program that needs to manipulate a tree structure (abstract syntax tree).
In the tree a node owns its children as unique_ptr and looks like:
struct Node {
// to replace node itself in the tree:
// points to unique_ptr that owns this node
// a node can be stored in different unique_ptr types
// -> for example: NodeY could be stored in unique_ptr<NodeY> or unique_ptr<NodeX>)
// -> thus self has to be of type unique_ptr<Node>*
unique_ptr<Node> *self;
// ...
};
struct NodeX: Node {
unique_ptr<Node> child1;
unique_ptr<NodeY> childY;
};
struct NodeY: Node {
unique_ptr<NodeX> child1;
unique_ptr<NodeY> child2;
vector<unique_ptr<NodeY>> otherChildren;
};
struct NodeZ: NodeY {
// ...
};
// and a lot of other nodes with different child types ...
While changing the tree it should be possible to replace a node in the tree.
For that purpose i store a self
pointer to the owning unique_ptr in each node. A replacement action would look like:
// could replace node:
void visitNodeY(NodeY *node) {
if (node->someCondition) {
// replace
auto newNode = make_unique<NodeZ>();
unique_ptr<Node> *self = node->self;
// replace with make_unique<NodeA>() would break inheritance hierarchy, but i will not do it :)
*self = move(newNode); // replace and delete old node
node = self.get(); // get new address
node->self = self; // self still points to same address, only contend of unique_ptr has changed
}
}
Now the problem is to set the self
pointer after constructing a node.
To achieve that i am using reinterpret_cast
:
void createNodeX_children(NodeX *nodex) {
// create childY
nodex->childY = make_unique<NodeY>();
// ...
// is that save?
nodex->childY->self = reinterpret_cast<unique_ptr<Node>*>(&nodex->childY);
}
My Question is now: is it save using reinterpret_cast in this way, as long i don't break the inheritance hierarchy like mentioned above?
Don't reinterpret_cast
. You can use std::unique_ptr
's constructors to transfer ownership polymorphically.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.