I am working on a problem in which we have a binary search tree made of nodes. The node's attributes consist of string, pointer to left node, and pointer to right node. I have a class called TransactionNode that is a subclass of node. TransactionNode has an int (for amount sold) as well as the same attributes from node class. I have a function called findBiggest that looks for the highest amount sold from TransactionNode and returns a reference to that TransactionNode. My problem is how do I convert something that is from the node class to TransactionNode? (I am avoiding changing the nodes in the binary search tree to TransactionNodes)
TransactionNode & BST::findBiggest()
{
TransactionNode * rightSide;
rightSide = this->mpRoot;
while (rightSide != nullptr)
{``
//find biggest transaction
}
return rightSide;
}
In general, if you need to check if an object pointed to by a base class pointer is of the derived class type, you use dynamic_cast
In your case you could try inside your while loop:
TransactionNode* txnNode = dynamic_cast<TransactionNode*>(rightSide);
if (txnNode != nullptr)
{
int amtSold = txnNode->GetAmountSold();
}
You may also consider having a virtual method in the base class and rely on polymorphism. Usually that is a preferred way over dynamic_cast. However, it may be that your Node class is too high level and does not need to support a "GetAmountSold()" method, but that is something you can decide.
Related
I want to build a n-arry tree from a document. For that i have 3 different types of elements for the tree:
Struct Nodes
Have a name
can contain other Nodes
Depth
Element Node (Leaf of the tree)
Have a Key
Have a value
Depth
Element Template Node (Leaf of the tree)
Have a placeholder which should be resolved later in the program
Depth
At the moment i think about something like this:
class Node {
public:
Node(int depth);
int depth() const;
private:
int depth_;
};
class StructNode : public Node {
...
private:
std::vector<std::unique_ptr<Node>> children;
};
class ElementNode : public Node {
...
};
class ElementTemplateNode : public Node {
...
};
The Tree will be generated from an File on Startup and reused to create an output string like this:
Structname:
key = value
key = value
Structname:
key = value
Structname:
key = value
...
Where the Key and value where directly read from the ElementNode or read from another file with the value of the placeholder inside the ElementTemplateNode
Is there maybe a better Structure for the Tree? Because with the current one i have to check first if its a StructNode, ElementNode or ElementTemplateNode
This is a typical structure for implementing a tree with different kind of nodes. Another variant would be the composite pattern.
The problem that you describe, is usually caused by asking the nodes about what they know, instead of telling them what to do. If you'd do it the other way round (tell, don't ask), you could get rid of those checks and benefit from polymorphism.
The different kind of nodes inherit from Node. You could design your tree using a uniform interface, with virtual functions defined for Node which then can be overridden for the different types of nodes. Calling the method would then do the right things, without need for a manual type check. For generating the output string, you'd tell the root node to generate a string. If it's a structure, it would add the heading and tell its children to generate a string, but if it's a leaf it would just add the key/value pair to the string. No need from outside to know anything about each node.
If the operation of exploring the tree shall not be implemented by the tree itself, the usual approach is to use a visitor pattern. The big advantage is that you write the vistor once, and it's then easy to specialize a new kind of visitor for different algorithms. Again, no need to check the type of the nodes. The pattern makes sure that the right elementary function is called for the right type of node.
I want to create a Binary search tree which has special Nodes. There should be three classes of Nodes, Internal Node, External Node and Root node, each inheriting a common parent Node and each type of node will have some unique function. Is it possible to create such a BST. The problem I am facing is suppose the first node I insert into the tree becomes the root node. The next node I insert will become External Node. Now if I insert another node then the external node has to become a internal node and the new node will become the external node. Also I cannot find a way to navigate through the tree from one node to another as the nodes will be of different types. Can a tree of this type be created. If yes then give me some suggestions of how this can be done.
If I understand correctly, you're worried about how objects in one class - External - need to become objects of another class - Internal. This, when C++ is a statically-typed language: Types (including the classes of objects) are determined at compile-time. Right?
Well, you can achieve this in at least one of two ways:
When an External node becomes Internal, delete the External node and replace it with an Internal node, properly initialized (e.g. to point at the new External node).
Give up on External and Internal being discrete types, and just check for children and parents to determine the node type dynamically.
Some more relevant reading material on these matters:
(Programming language) type systems in this Wikipedia page.
This SO question: What is duck typing?
The Circle-vs-Eclipse problem, and specifically the desire to stretch circles into ellipses.
You could use basic inheritance some type enum and recursive calls.
This could be a starting point:
enum NodeType
{
eRoot,
eInternal,
eExternal
};
class BinaryNode
{
public:
virtual NodeType GetType() = 0;
virtual void UpdateTree() = 0;
protected:
BinaryNode* ChildLeft;
BinaryNode* ChildRight;
BinaryNode* Parent;
};
class ExternalNode : public BinaryNode
{
NodeType GetType() override { return eExternal; }
void UpdateTree() override
{
//... Replace node instances here(e.g. delete this node and construct the correct new one given this sub tree. call new InternalNode(this) for example)
// Call this towards the parent node so the tree will be transformed accordingly
}
}
class InternalNode : public BinaryNode
{
NodeType GetType() override { return eInternal; }
void UpdateTree() override { //... }
}
class RootNode : public BinaryNode
{
NodeType GetType() override { return eRoot; }
void UpdateTree() override { //... }
}
This is just to give you an idea where to start. You can check the node type at runtime via GetType() and do some checks based on that.
Be aware that this kind of transformation is not particularly fast.
If you want this to be fast, don't use different types and virtual function calls and pointers.
Place your binary tree inside an array and use binary indexing, so at a given index "n" use 2*n+1 to get the left child and 2*n+2 to get the right child. Then use some flags (root, external, internal etc.) to determine which functions you want to call on the binary node. I wouldn't use inheritance like in my code example to be fast or more readable. In fact, deciding externally what functions to call on a node can be much more readable and less error-prone.
I'm writing a k-d tree, which I think is good enough at this point. I've put the whole template at http://private.org.il/Code%20Projects/kd%20tree%20w%20bb%20cache.zipx
One thing I'd like to do is eliminate RTTI, and specifically calls to dynamic_pointer_cast.
_____________________ Edit with more info _____________________
The relevant part is that I use three classes: an abstract node class, that requires it's derived classes to implement the isInternal() function.
There are two classes that derive from it - an internal node class (function returns true), and a leaf node class (function returns false). Therefore, once isInternal is called, I know to which of the two derived classes the pointer can be casted to.
The one routine I'm having problem eliminating the call is ApproxNearestNeighborNode, which provides an initial guess for the nearest neighbor search. Currently it looks like this
shared_ptr<kd_leaf_node> ApproxNearestNeighborNode(const kd_point &srcPoint) const
{
unsigned int Depth = 0;
shared_ptr<kd_node> Node(m_Root);
while (Node->isInternal())
{
shared_ptr<kd_internal_node> iNode = dynamic_pointer_cast<kd_internal_node>(Node);
if (srcPoint[Depth++%K] <= iNode->splitVal() || iNode->Right() == nullptr)
Node = iNode->Left();
else
Node = iNode->Right();
}
shared_ptr<kd_leaf_node> lNode = dynamic_pointer_cast<kd_leaf_node>(Node);
return lNode;
}
The two issues that baffle me is keeping the routine iterative, rather than recursive, and returning a smart pointer to the leaf node.
[OK, I think there's a way to do it using shared_from_this, I just hope there's a way to do it rewriting as little code as possible.]
Any other feedback would be appreciated, but off topic, so please send it by email.
As noted by πάντα ῥεῖ, you can replace dynamic_pointer_cast by static_pointer_cast. It seems that your Node->isInternal() check is meant to ensure the dynamic case always succeeds, so a simple search-and-replace is enough.
We have a base class.....
class Node
{
public:
std::string Name;
Node(){};
~Node(){};
}
Filter is a derived class of Node.
Filter is the same a node, except it has a 'filterId' property and it's constructor populates Node.Name='Filter'.
class Filter: public Node
{
public:
int filterId;
Filter() : Node()
{
Name="Filter";
}
}
I have a ClassFactory that returns std::shared_ptr<Node> when passed a string
Please find the code to that factory on CodeProject following this link.
http://www.codeproject.com/Articles/567242/AplusC-b-bplusObjectplusFactory.
The code seems to instantiate a Filter, but, returns a Node. i.e. Object slicing.
std::shared_ptr<Node> n = std::make_shared(Node); // As expected, doesn't not have filter ID and node.Name is blank.
std::shared_ptr<Filter> f = std::make_shared(Filter); // As expected, has filterID and node.Name is 'Filter'.
Now i want to handle an array of std::shared_ptr(Node) which may actually contain std::shared_ptr(Filter) depending on what the class is requested from the factory.
std::shared_ptr<Node> nf = std::make_shared(Filter); // Error. Does not have filterId, but does have **Node**.Name='Filter'.
I even tried the simpler case..... and got the same problem.
Node n = Node();
Filter f = Filter();
Node nf =Filter(); // Error, nf does not have a filterID, but it's Name field is set to 'Filter'.
What am i doing wrong here? The Node is a base class for all of my derived classes. When i have a function that accepts a Node, i should be able to send it a Filter and have the filterId available.
Pointers are advised to help in situations like this, however the shared_ptr is a pointy as things will get.
Node doesn't have any knowledge of additional data members and functions that derived classes may define. So you need to retrieve a shared_ptr<Filter> to be able to access filterId. Use std::dynamic_pointer_cast to do this.
std::shared_ptr<Node> n = ...
auto f = std::dynamic_pointer_cast<Filter>(n);
if(f) {
// The managed object is a Filter
std::cout << f->filter_id << '\n';
}
Live demo
And if you know that n always contains a Filter (or something derived from Filter), you can use std::static_pointer_cast instead.
When you have any manner of pointer or reference to the base class, you can only access the things that the base class API exposes. If you want to access filterId, you need to either:
add it to the base interface (perhaps with a function that returns a boost::optional<int>, or pair true,filterId when available, otherwise e.g. false,0) or
see if you can std::dynamic_pointer_cast to the Filter type, if the returned pointer is true in a boolean context, you can use it to access the filterId.
I'm writing a decision tree based algorithm (ID3). I use two classess to represent a node. ResultNode, and TestNode. ResultNode is kind of leaf. It simply contains a result with a method to aquire it. TestNode is simply not-leaf. It has an array of children, and test function.
The most basic approach is create more general class Node which would provide interface for both of them, however both test, and getResult are specific to it's classess. Having test function in ResultNode doesn't make any sense, as well as having getResult in TestNode. They should just return any value for opposite classess, and never be used.
class Node {
public: //I don't care about encapsulation in this example
bool is_leaf;
virtual int getResult() { return 0; } //int because, type isn't important here
virtual int test() { return 0; }
}
Then I must be aware to call only functions appropriate to object type (hence boolean variable). The only thing I can do to protect the code is inserting some ugly macro that throws warnings when original functions are called. But all this pattern look very ugly in my opinion.
Of course I can also move those functions to desired subclassess, but as all pointers are Node type I would need to use casting in order to call those methods, which is way more uglier. (even my supervisor says so)
Now I wonder, whether it would be any better if I had used a function that returns a reference of given type:
TestNode& getTestNode() {
return *nodePointer;
}
I am almost sure that there is a design pattern that use such technique, but I looks like a nasty hack to me.
Edit:
After some research I found out that you can deal with casting problem from my second approach using a Visitor or Command design pattern.
In actual use it seems that the concept of a TestNode is that it ultimately allows getting a ResultNode - so Node can have a getResult method that for a TestNode walks down the tree and for a ResultNode returns this -- the test method is likely a private method of TestNode that is used to find the ResultNode.
Something like:
class ResultNode;
class Node
{
public:
virtual ResultNode * getResult() = 0;
};
class TestNode : public Node
{
public:
virtual ResultNode * getResult() {
/* does things to find next TestNode or ResultNode */
return found->getResult();
}
private:
test() { ... }
Node * children; // dynamic array of Nodes (TestNode or ResultNode)
};
class ResultNode : public node
{
virtual ResultNode * getResult() { return this; }
}