How to eliminate RTTI in sample code - c++

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.

Related

Two versions of the program depending on the input parameter without code duplication

I am solving the following problem. I am working on an optimization program in C ++ which, depending on the initial settings of the user, uses various regulations (standards) to calculate the target function. Suppose we have a method A based on some norm and a method B based on another norm to calculate the target function. The user is setting the right standard before starting the program. The rest of the code is the same. During optimization, the target function is iteratively called over and over again. Of course, there is a simple solution: each time the target function is called, the IF condition is used to decide which standard to use. But because the program has to make decisions in every iteration, it seems to be ineffective. The second option is to create 2 independent codes and run only the one with the required standard. This, in turn, is ugly in terms of duplicate code.
I imagined that I would create 2 different classes and use the selected class using the IF condition when constructing the object. This would make the program decide only once when creating the object, but during the iteration itself the object would be clearly defined. Unfortunately, this does not work because objects cannot be created in IF conditions.
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") Sensor_Uniaxial_025 sensor(data);
else if (data.sensors_tipe == "T_rosette_05") Sensor_T_rosette_05 sensor(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensor.rotate(element_index, orientation_angle);
Another way I would like is to set the correct method using a parameter in the constructor. Unfortunately, that probably isn't possible either.
I am a beginner and I did not find the answer anywhere. So maybe someone can help. Thanks
This is a good job for templates, which are "recipes" to generate code.
The end result will be duplicated machine code, but without the duplication in the source.
template<typename MethodT>
float optimize(const MethodT& method) {
float v = method();
// etc...
}
float methodA();
float methodB();
int main() {
auto a = optimize(methodA);
auto b = optimize(methodB);
}
First, the solution with if may be not that bad. It is branch on each function call, but the branch should be predicted well.
Second, if the functions that implement method A and method B are large enough to miss inlining, use function pointer.
Otherwise, use static polymorphism with templates, method A and method B may be passed via template parameter as functors.
In case, the user can change standard after programm compilation (for example, before each run) you can create interface and 2 child from it.
So, at startup you should create the instance (one of 2) you need through new. And then you can use it.
You can't use that algorithm with stack instances.
One way is to use inheritance.
class Sensor
{
public:
virtual void rotate(int, double) = 0;
};
class Sensor_Uniaxial_025 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
class Sensor_T_rosette_05 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
Sensor* sensorToUse;
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") sensorToUse = new Sensor_Uniaxial_025(data);
else if (data.sensors_tipe == "T_rosette_05") sensorToUse = new
Sensor_T_rosette_05(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensorToUse->rotate(element_index, orientation_angle);
The example above, with new, comes with serious memory management issues. But if you pre-allocate the sensor for each type, in a single instance, and use a look-up instead it works well.
The alternative is with template. See other answers for these approaches.

Converting subclass to base class?

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.

Saving a pointer vs passing value as const

This is something from the theory of c++ which I never quite got.
I have very large list of small structures (in size) called nodes inside Class A.
So I have:
private:
QList<Node> nodes;
Now Class A has instance of Class B (called cB) and for one of its functions it requires to iterate over nodes and just read them (it will not modify the information in any way).
function ClassB::readNodes(){
for (int i = 0; i < nodes.size(); i++){
// READ nodes and do stuff with that information
}
}
So as far as I know there two ways to approach this. This is my current approach Inside Class B I have:
public:
void setNodes(const QList *list) {nodes = list;}
private:
QList<Node> *nodes;
And then somewhere in Class A I do:
cb.setNodes(&nodes);
The objective of this approach is that I want to avoid copying a very large data structure each time readNodes() is called, and also there is only one copy of the data structure in memory. This is important because Class A will continually change nodes.
The second approach is much simpler and more clear in my opinion. Simply define readNodes as:
function ClassB::readNodes(const QList<Node> &nodes){
for (int i = 0; i < nodes.size(); i++){
// READ nodes and do stuff with that information
}
}
But I'm not totally sure that this will insume a performance penalty. As far as I understand it this approach also treats nodes as a reference and so no deep copy of nodes occurs. Is this correct?
Most of the Qt classes(including container classes) are implicitly shared. So even if you pass them around by value, there won't be a deep copy until you access to those items.
Passing const references of objects is a more general and safe approach though.

access list from class, in parent

I'm new to C++, and have experience with other programmas languages, but I have a question:
How can I access a list from a sub class, from the parent?
Here is my layout:
TutorialApp.cpp with function TutorialApp::update()
In that function I want to access the list mParticles2y from another class
that list is made in: ParticleController.cpp, like this:
std::list<int> mParticles2y;
I've tried accessing the list like this [in TutorialApp]:
mParticleController.mParticles2y.size() [to get it's size]
but that gives me this error:
call of an object of a class type without appropriate operator
So I dont really know where to go from here...
PS: I use mParticleController because that is state in my script:
ParticleController mParticleController;
I hope this is enough info.
PS: I'm not really sure this is called a class, or child, I use these terms because I know them from ActionScript [which works with classes in a similar way]
Your code for the loop that has the errors should look more like this. It may not compile exactly since I can't compile it easily at the moment. This isn't the ideal way to go about it, but it is the minimal impact to your code. I would move this loop to the ParticleController class as a member function that returned true/false to indicate a hit. It would be better encapsulated that way.
for(std::list<int>::iterator yit = mParticleController.mParticles2y.begin(),
std::list<int>::iterator xit = mParticleController.mParticles2x.begin();
yit != mParticleController.mParticles2y.end() && xit != mParticleController.mParticles2x.end();
yit++, xit++)
{
if(
(coordy >= *it) && (coordy <= (*it) + 40) &&
(coordx >= *xit) && (coordx <= (*xit) + 40)
)
{
mParticleController.removeTargetedParticles(i); //remove blokje
score += 1; //score verhogen
}
}
Ok, so this is a shot in the dark, since your question, while very wordy, is short on code necessary to reproduce the issue.
You can only access public members (data or functions) of other objects. That is, in order to access mParticleController.mParticles2y, mParticles2y must be a public member of whatever type mParticleController is of.
Of course, public data member are frowned upon, and for good reasons. A class should represent an abstraction, and if you have a particle controller, it should implement everything necessary to control particles, rather than spilling its guts out in the public for everyone to sift through and take what they need.
This is called encapsulation, and one of the cornerstones of the object oriented paradigm.
size is a method, you need to write size().
The information you provide is somewhat ambiguous, but it looks like you may be attempting to access the private state (the list) of one class (the ParticleController) from another class (The TutorialApp).
I'm assuming the following code structure (note that I haven't tried to compile this so it might not be quite right):
#include <list>
class ParticleController
{
public:
ParticleController() {}
std::list<int> &getParticles2y() const
{
return mParticles2y;
}
private:
std::list<int> mParticles2y;
}
class TutorialApp
{
public:
void update()
{
// ...
ParticleController mParticleController;
//std::list<int> particles2y = mParticleController.mParticles2y; // error - accessing private member of another class
std::list<int> &particles2y = mParticleController.getParticles2y(); // OK
}
}

Pointer Reference Pattern - Common use?

In a system where current object is operated by other contained objects, when reference to current object is passed, it appears that the link goes on and on....without any end ( For the code below, Car->myCurrentComponent->myCar_Brake->myCurrentComponent->myCar_Brake->myCurrentComponent ....).
ICar and Car->myCurrentComponent->myCar_Brake refer to same address, point to same objects. It's like Car contains Brake which refers to Car.
In fact, Car is the only object, myCar_Brake and myCar_Speed just refer(point) to it.Is this kind of use of reference and pointer normal? Are there any potential problem with this approach?
Sample Code
class Brake
class C
class Car
{
public:
Car();
// Objects of type B and C.
Brake* myBrake;
Speed* mySpeed;
// Current component under action.
Component* myCurrentComponent;
}
/******************************/
// Constructor
Car::Car()
{
myBrake = new Brake(*this);
mySpeed = new Speed(*this);
myCurrentComponent = myBrake;
}
/******************************/
class Brake: public Component
{
public:
Brake(Car&);
// Needs to operate on A.
Car* myCar_Brake;
}
// Constructor
Brake::Brake(Car&)
{
myCar_Brake = Car;
}
/******************************/
class Speed
{
public:
Speed(Car&);
// Needs to operate on A.
Car* myCar_Speed;
}
// Constructor
Speed::Speed(Car&)
{
myCar_Speed = Car;
}
/****************************/
There's no fundamental problem with having circular references in your object graph, so long as you understand that and don't try to traverse your object graph without keeping track of which objects you've encountered. To specifically answer your question, having circular references between objects is relatively common; it's the way a doubly-linked list works, for example.
Although, as Paul mentions, there is no problem with having circular references, the above code example is totally missing encapsulation and is not memory leak safe.
Does it make sense to allow something like this?
Speed::Speed(Car& value)
{
myCar_Speed = value;
// WTF code below
value->myCurrentComponent->myCar_Brake = NULL;
}
Also,
Car::Car()
{
myBrake = new Brake(*this);
mySpeed = new Speed(*this);
//if Speed::Speed(Car&) throws an exception, memory allocated for myBrake will leak
myCurrentComponent = myBrake;
}
Never use raw pointers without some kind of a resource manager.
Without debating the validity of the actual object structure of the relation of Car, Break and Speed, this approach has one minor problem: it can be in invalid states.
If - something - goes wrong, it is possible in this setup, that a Car instance#1 has a Break instance#2 that belongs to a Car instance#3. A general problem with doubly-linked lists too - the architecture itself enables invalid states. Of course careful visibility modifier choosing and good implementation of functions can guarantee it will not happen. And when its done and safe, you stop modifying it, take it as a 'black box', and just use it, thus eliminating the probability of screwing it up.
But, I'd personally recommend to avoid architectures that allow invalid states for high level, constantly maintained code. A doubly-linked list is a low level balck box code that will most likely not need any code changes, like ever. Can you say that about your Car, Break and Speed?
If a Car had a Break and Speed, and Break and Speed would not know of their "owning Car", it would be impossible to make and invalid state. Of course, it might not suit the concrete situation.