I have a class that is a bit complex to initialize. It is basically a tree structure and to create an instance the current constructor takes the root node. Nevertheless there are some instances that will be used more often than others. I would like to make it easier for the user to instantiate this ones faster and easier. I was debating what the best option would be.
First option: using enum
to choose between different options in the constructor.
enum CommonPatterns {TRIANGLE, DIAMOND};
typedef struct PatternNode {
int id;
vector<PatternNode*> child;
} PatternNode;
class Pattern {
private:
PatternNode root;
public:
//Constructor that takes the root of the tree
Pattern (PatternNode root) { this->root = root; }
//Constructor that takes enum to create some common instances
Pattern (CommonPatterns pattern)
{
PatternNode predefined_root;
if (pattern == CommonPatterns::TRIANGLE)
{
//Build tree structure for the triangle
}
else if (pattern == CommonPatterns::DIAMOND)
{
//Build tree structure for the diamond
}
Pattern(predefined_root);
}
}
Second option: predifining some static instances
Pattern.h
enum CommonPatterns {TRIANGLE, DIAMOND};
typedef struct PatternNode {
int id;
vector<PatternNode*> child;
} PatternNode;
class Pattern {
private:
PatternNode root;
static Pattern createTriangle();
static Pattern createDiamond();
public:
//Constructor that takes the root of the tree
Pattern (PatternNode root) { this->root = root; }
//Predefined common instances of patterns
const static Pattern TRIANGLE;
const static Pattern DIAMOND;
}
Pattern.cc
Pattern::Pattern createTriangle()
{
PatternNode root;
//Create the tree for the triangle
return Pattern(root);
}
Pattern::Pattern createDiamond()
{
PatternNode root;
//Create the tree for the diamond
return Pattern(root);
}
Pattern Pattern::TRIANGLE = Pattern::createTriangle();
Pattern Pattern::DIAMOND = Pattern::createDiamond();
I don't understand that well the implications of using static performance wise so I would appreciate some suggestions.
CodePudding user response:
As usual when people ask for the performance benefits, the first rule of optimization of code applies: If you think, you have a performance problem, measure the performance.
So my (and many a a people's) opinion is, that you should treat this problem with other things in mind, e.g. what is more clear to the user and/or the reader of the code (which is often yourself, so be extra nice to them!) or what code structure makes it easier to test. Unfortunately those are a bit up to opinion, so now I will share mine:
Having separate functions for these seems cleaner to me.
- It means that for testing purposes you have more but smaller tests, which makes it easier to spot the exact problem, when a test fails.
- Related: The constructor is smaller and hence less error prone.
- For the user it is extremely specific: He gets a function in the class namespace whose name says what it does.
If you go that route, remember to document these static functions in a way that a user will stumble upon them, e.g. mention them in the class documentation and/or the constructor documentation. Although the same holds for documentation of the enum.
Lastly let me hazard a guess regarding performance: Although I don't expect any noticable performance issues either way, the static function version has the advantage that the compiler may optimize it more easily as it (seems to) depends only on compile-time data.
Again to really find out about performance, you would have to
- measure the performance differences or --even better--
- disassemble the code and see what the compiler actually did with your code.