Home > Software design >  Predefined instances of C class enum vs static
Predefined instances of C class enum vs static

Time:10-15

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.

  1. 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.
  2. Related: The constructor is smaller and hence less error prone.
  3. 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

  1. measure the performance differences or --even better--
  2. disassemble the code and see what the compiler actually did with your code.
  • Related