Showing posts with label code patterns. Show all posts
Showing posts with label code patterns. Show all posts

Saturday, 18 October 2025

On the Topic of "Smart Pointers" and the Factory Create Pattern

This is a topic I have visited a few times over the years:

2016, 2016 on SDL2, 2019, 2023 on control block, and I visited it professionally on the now cancelled AAA MMO Game Engine with Zenimax Online; the specific pattern within which came from my original 2016 post, just with a few tweaks and expansions over the years.

Its just one of those things which comes up time and again in the C++ space, much like my crusade against return early in performance code... cough.

And it came up again just this week, where given a coding test I immediately did not like seeing raw pointers being used, so quickly refactored it to use a factory create pattern, except I was in a rush and didn't have the luxury of a whole game engine backing me up.

So denuded of even my own post I quickly used a different approach, so use a hidden (private) member struct in the constructor.  The constructor remains public so std::make_shared or std::make_unique can access them without hinderance from the static create factory member function, but that a regular user can not use a flat "operator new" as they can not access the private struct.... Sounds complex, but it's really not, and you will even find this exact pattern on CPP Reference sites across the web, let us quickly output an example (and I'll assume you've taken a look at my prior post from 2016 above for the actual "shared pointer friendship" I would prefer).

struct Thing
{
private:
   struct HiddenInternal {};    // Just an empty struct
public:
    using Ptr = std::shared_ptr<Thing>;

    static Ptr Create()
    {
        return std::make_shared<Thing>(HiddenInternal{});
    }
    explicit Thing([[maybe_unused]] HiddenInternal internal)
   {
   }   
};

And so with this code we can only get a Ptr instance here from the static Create call.

Now I've set the scene, what am I asking myself?  I'm asking what is the compile time and what is the runtime effect of these two patterns?

Compiletime my suspicions are that the shared_pointer friendship stuff in my original post is more weight to carry, there's a macro in my more complex implementations, so that's pre-processor overhead, there's expansion of the code at compile time.

But there's also this HiddenInternal in this new, simpler, implementation based solve; I believe there will even be compiler ellision of the HiddenInternal as its empty and does nothing; I just need to observe and understand this topic better.

Lets start with Compiler Explorer and my first confirmative discovery, just as I suspected, the compiler is very smart smart and it will easily see a trivial class such as mine above, or one with a single member, and fold it away to nothing in compiler ellision.

And this is a great thing!  It proves at zero runtime overhead whilst we have code fully communicative of the intent, self documenting code is a wonderful thing, and this is an interesting and eye catching pattern in the code.... Such that I believe even a new set of eyes meeting it would appreciate there is something special intended and they would take care to use the class properly, avoiding memory leaks for us along the way.

Good code health is as important as the final result, I especially take pride in code which can run a long duration.  I've always worked on long lived project timelines.

So HiddenInternal can result in no overhead when the class is trivial, what about when the class is complex?

The first thing I notice is that the factory creation function itself generates no code, yet we benefit from its intent at compile time and in the usage.  There is of course the control block creation for the shared pointer in this instance and I hold that in my mind, but the cost to pay back in intent of the code far outweighs the control block.

The constructor itself is interesting.... 


Removing the HiddenInternal gives no difference, so the compile has still removed the empty class, but enforces it's use in the code... This is a total win-win... The cost at compile time, one compile time ellision in one translation unit which is neglegable.

The runtime overhead zero.

What about the preprocessor and friendship.... The friend keyword itself is zero cost, the wrapping of it in a macro is therefore arguably a different conversation to have.  Resolving a friendship however is not so cost effective, the friend keyword adds a symbol, typically with a cost of O(1).

The look up from any other resolve is therefore either going to be O(1) or O(log N) where N is the number of other appearances of the name, this look up is going to be the compile time cost.  In practical terms this is going to be a very small duration, perhaps even below measurable in the pantheon that is a build across multiple cores.

A friendship link itself however costs nothing in code generation time, so we do not hold up the compile per se, we do however add a cost in the symbol table build.

Once something is in the symbol table it will result in complexity when refactoring code, potentially more rebuilds if the friendships, or classes within change.

In conclusion, if I have the option to set up a friendship to the underlying control block (see 2016) I would, but equally to keep the local complexity low I would also consider the Hidden private member class as a "trick".

Monday, 10 October 2016

Software Engineering : 5 minutes 33 seconds every C++ developer should watch

Just... Just go watch this, digest it...


I've love to print this out frame by frame, phrase by phrase, and have developers walking through the door recite a line at random every morning.

Tuesday, 4 October 2016

Software Engineering : C++14 Factory Create Pattern for GCC

In my previous Software Engineering item, I covered a factory create pattern, to prevent programmers using my classes with their vanilla constructors, forcing them into using a smart pointer in the hope that they would never get a memory leak from using my classes (assuming my classes clean up cleanly internally).

This pattern can be seen here, but is specific to the Microsoft STL implementation of the Memory classes.

On Linux however, with GCC, you have to make a different class a friend, this is "__gnu_cxx::new_allocator", which like "_Ref_count_obj" is an implementation of a counter to references to the allocated class type.  It is also templated, and used exactly the same way as the Microsoft version.

Use it like this:


You can see my whole screen, with all the code here:

Click to Zoom in

On the left is the example code, on the right you see me invoke g++ with C++14 to compile and then run the example program.

The code clearly shows the private constructor, it's a trivial class, if any of that confuses you then this maybe too advanced an item for you to pick up on just yet, but do come back and learn this, as it's very useful when you've built up your C++ confidence.




Tuesday, 13 September 2016

Software Engineering : C++14 Factory Create Pattern

For the GCC version of this, see this post (at the time of writing this link is to a scheduled item, it may not work just yet, scheduled for Tuesday 4th October 2016 at 18:30 GMT+1).

I commonly employ a "Factory Create" style to my classes in C++, the reason being I like to take control over the specific way that classes can be created, rather than relying on the compiler to always create the default constructors for me.  I like the constructors, but it leads to the problem of memory leaks, lets take a look at a bad example:


With this class any programmer can then do:

Alpha* l_somevalue = new Alpha(42);

They can then forget to call "delete l_somevalue;" and therefore leak memory.

We would therefore like to hide the constructors away, to prevent their miss use:


This necessitates we do expose someway to create an instance of the class, and that instance be wrapped as a smart pointer...


The first thing we see is a forward declaration of the class, then it's type wrapped as a smart pointer (a shared pointer in this case).  Next we see the various constructors have been made public, curing and removing all possibility of the programmer leaving hanging pointers to instances of our class.

Finally, we see a set of static "create" functions, our method to create an instance of the class now would look like this:

BetaPtr l_instance = Beta::Create();

When the reference count to the l_instance copy drops to zero then it will be automatically cleaned up, this is the whole point of this programming pattern.

There is nothing wrong with this code at the moment, we can define the constructors, knowing they can't be used outside the class, like this:


And the create functions look like this:


So far, we've learned nothing new... So what is new?... Well in C++14, really we should not be calling "new" at all.  The moment we see new outside the class we should implement this whole code pattern to hide the constructors away, exposing only smart pointers.  And likewise internally to those create functions we should not be calling "new", we should be using "std::make_shared".

Like this:


The problem?...


Hmmm... "error C2248: 'Beta::Beta': cannot access private memory declared in class 'Beta'", what is this telling us?

That the constructor of Beta could not access one of the private members of itself?  Huh?.. That makes no sense, of course the constructor should be able to access its own member!

What else does the error tell us?  "File: memory"... memory?... Not my code file, but the memory header?  We can open that location and take a look, what is the location of the error representing?


The _Ref_count_obj, the actual location that a shared_ptr is instantiated and the forward passed the arguments to the constructor, so the error is NOT that the constructor of our class can't get at it's private member, but that the template wrapped reference count object, which we inherit from because of the use of "make_shared", that reference can't get at the private members of the class!

How to solve this?... Simple:


Simply adding the "friend std::_Ref_count_obj<Beta>" allows that inherited class from "<memory>" to see inside the private area of the Beta class, and we enable the clean use of std::make_shared thereafter.

I highly recommend removing your constructors from prominence, and the use of "Factory Creation", as to other much more authoritative figures then myself.

My Complete code is below!

#include <iostream>
#include <memory>


class Alpha
{
private:

int m_AlphaValue;

public:

Alpha();
Alpha(const int& p_NewValue);
Alpha(const Alpha& p_OtherAlpha);

const int Value();
void Value(const int& p_NewValue);
};



class Beta;
using BetaPtr = std::shared_ptr<Beta>;
class Beta
{
private:

friend std::_Ref_count_obj<Beta>;

int m_AlphaValue;

Beta();
Beta(const int& p_NewValue);
Beta(const Beta& p_OtherBeta);

public:

static BetaPtr Create();
static BetaPtr Create(const int& p_NewValue);
static BetaPtr Create(const BetaPtr& p_OtherBeta);

const int Value();
void Value(const int& p_NewValue);
};


Beta::Beta()
:
m_AlphaValue(42)
{
}

Beta::Beta(const int& p_NewValue)
:
m_AlphaValue(p_NewValue)
{
}

Beta::Beta(const Beta& p_OtherBeta)
:
m_AlphaValue(p_OtherBeta.m_AlphaValue)
{
}

BetaPtr Beta::Create()
{
return std::make_shared<Beta>();
}

BetaPtr Beta::Create(const int& p_NewValue)
{
return std::make_shared<Beta>(p_NewValue);
}

BetaPtr Beta::Create(const BetaPtr& p_OtherBeta)
{
return std::make_shared<Beta>(*p_OtherBeta.get());
}




int main()
{
Alpha* l_Instance = new Alpha(42);
std::cout << "Alpha: " << l_Instance->Value() << std::endl;

BetaPtr l_BetterInstance = Beta::Create(42);
std::cout << "Beta: " << l_BetterInstance->Value() << std::endl;

// No need to delete l_BetterInstance, it cleans itself up

// Whoops... l_Instance of alpha leaks!
}

Tuesday, 12 July 2016

Software Engineering : Arduino Uno - Flashing Clock

What is this flashing clock?  Well, it's just an arduino uno, with three LED's, one each for the seconds, minutes and hours.  They don't show the time, they just flash as each period they're counting passes.

So, we're going to count the seconds and flash just the second LED.  Then each 60th flash, we reset the seconds counter, increment the minute counter and have the minute LED flash.  Ditto for the hour counter each 60th minute.

I've got the LED's VCC legs connected to digital pins 8, 9 and 10, with the other connected to the three grounds.  When I come to make this an actual board I can have a single ground pin being used up, rather then using all three on the board.

An important part of the code to focus on is how to turn on each light in turn...

If you want to turn on the second, the minute and the hour LED all at the same time, you could have some horrid "if" statement controlling them, but much more clean looking is this:

// Turn lights on
switch(CycleCount)
{
    case 2:  digitalWrite(HourPin, HIGH);
    case 1:  digitalWrite(MinutePin, HIGH);
    case 0:  digitalWrite(SecondPin, HIGH);
                break;
}

So, the count is reset to zero each cycle it is incremented if we add to the minutes, and incremented if we add to the hours.

The switch statement then drops through, notice that there are no "breaks" on the 2 and 1 (hours & minutes) cases.  So, if we have incremented the hour, we have a count of two and so we set the HourPin High, drop through to the MinutePin High and finally the Second Pin High before we break.

Likewise, if we only set the minutes this cycle, then the count will be one, so the switch statement will drop down to the Minute Pin high, skipping the Hour pin totally.

The effect of this is to seemingly instantly turn on all the LED's each cycle as they are needed together, there is no humanly noticeable staggering of the lights coming on, as one might get with an if statement, or once might get if one were to set the LED as we increment the values.  Doing Lights on when we increment actually clearly shows the LED's going on and off in a staggered pattern.

Our task after turning all of them on is to just wait a short time (100 milliseconds) and then turn them all off with another switch statement.  And with them all off again simply wait for the remainder of the second (i.e. 900 ms).


Keep this in mind as you read the following code:

// The pins
int SecondPin = 8;
int MinutePin = 9;
int HourPin = 10;

// The counts
int CycleCount = 0;
int SecondCount = 0;
int MinuteCount = 0;
int HourCount = 0;

void setup() 
{ 
  // Setup the pins
  pinMode (SecondPin, OUTPUT);
  pinMode (MinutePin, OUTPUT);
  pinMode (HourPin, OUTPUT);
}

void loop() 
{
  // Increment the counts
  CycleCount = 0;
  SecondCount = SecondCount + 1;
  if ( SecondCount > 59 )
  {
      SecondCount = 0;
      ++MinuteCount;
      ++CycleCount;

      if ( MinuteCount > 59 )
      {
        ++CycleCount;
        MinuteCount = 0;
        ++HourCount;

        if ( HourCount > 23 )
        {
          HourCount = 0;
        }
      }
  }

  // Turn lights on
  switch(CycleCount)
  {
    case 2:
      digitalWrite(HourPin, HIGH);
    case 1:
      digitalWrite(MinutePin, HIGH);
    case 0:
      digitalWrite(SecondPin, HIGH);
      break;
  }   

  // Light are on for 1/10 of a second
  delay(100);

  // Tuen lights off
  switch(CycleCount)
  {
    case 2:
      digitalWrite(HourPin, LOW);
    case 1:
      digitalWrite(MinutePin, LOW);
    case 0:
      digitalWrite(SecondPin, LOW);
      break;
  }   

  // Lights all off for 9/10 of a second
  delay (900);
}

If you found anything of use here, please return again, and don't forget to check out my other YouTube videos.

Friday, 24 June 2016

Software Engineering : C++14/make_shared & Factory Create Pattern

I have a C++ issue, it's not often I can pick fault, but this is one of them... For years, I've used the factory create pattern; or at least my take on that pattern.  

Whereby I make the constructor private, or the whole class "Uncopyable/Uncreatable", and then I add a new static function which returns the class wrapped into a smart pointer.

By doing this, I get the advantage that no-one can use outdated "new" calls on it, and I drastically reduce the potential for third party memory leak creation/exploitation.

I can still do this with C++14, however, for a while now authors have recommended using "std::make_shared".  Their points are valid, but they break my factory creation pattern.  Which has much more to offer me than just using "make_shared" or whatever smart pointer creation template.

Lets take a look...


So, we have the class, but we're creating and deleting it in the old style, anyone forgetting to perform that delete will leak memory.


There, we can implement creating the class instance with a smart pointer...


A big change next however, we make the constructor private, to absolutely stop other programmers creating instances of our class with "new" and so totally negating anyone creating the class and potentially forgetting to delete it.

So we offer the programmer the static create function, which returns the shared pointer wrapped class... At least, that was the idea, as we can see, it utterly fails, because the std::make_shared template class is not a friend of our "foo" class.

Finally, we have to take a step back, to use the create, and hence enforcing our whole factory create pattern, we have to return this smart pointer wrapped instance after using "new".  This is fine, it is the same as "std::make_shared", but feels like a retrograde step.


Thursday, 8 May 2014

Domino Computing

As an adjunct to our C++ based Electronics Code.. How about Domino based computing?



Wednesday, 19 March 2014

Why I don't like Lambda's (C++)

Why I don't like Lambda's (C++)
I think I'm going to be in the minority of programmers when I say that I don't like Lambda's, in case  you don't know, a Lambda is a piece of code you an run inline, so you can create it and run it where you're working... like this:

#include <iostream>

int main ()
{
int sum10 = []
{
int i = 0;
for (int k = 0; k < 10; ++k)
{
i += k;
}
return i;
}();
}

When the code here is compiled & run, the value entered into "sum10" is the result of the function which follows, traditionally we'd write this code like this:

#include <iostream>

int Sum10Function ();

int main ()
{
int sum10 = Sum10Function();
}

int Sum10Function ()
{
int i = 0; 
for (int l = 0; k < 10; ++k)
{
i += k;
}
return i;
}

You can see this "Sum10Function" is actually a function, it has a declaration and a definition.  And this is how I'd always prefer to do work with functions, I do not like Lambda's because they ignore the greatest power of functions like "Sum10Function".

And that power is having a known location, a location you can find and a location which one can easily find all references to, you know if you have a problem in the function that you have one body to find and you can find it easily.  Finding a Lambda, written inline, in a mass of source is not a boon, it is in fact a major headache.

Other authors on the topic, such as "Alex Allain" (http://www.cprogramming.com/c++11/c++11-lambda-closures.html) actually have the balls to intimate that the fact you can write the function inline like the lambda, without having to stop and go create a prototype and a body declaration is a strength, but he; like many others; totally ignores the elephant in the room and that is the maintainability of code.

Alex's other examples on that page also start to use function pointer or functor examples, the first "AddressBook" class example he gives is taking a type, and yes we can assign a lambda to a type "auto"... but we can also assign a function pointer to an "auto", so there's no difference in using a function pointer or using a lambda in that example, except the Lambda falls foul of my point, it's harder to find and manage the source for the function.

The article linked there is also one of the major references if one googles for Lambda's in C++.  And it has code examples, which work, but which he describes as "pretty good looking", but which I see as horrible... here's the examples, cleaned up in the same program:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
using namespace std;

vector<int> v;
v.push_back(1);
v.push_back(2);
//...
for (auto itr = v.begin(), end = v.end(); itr != end; itr++)
{
cout << *itr << endl;
}
vector<int> vw;
vw.push_back(1);
vw.push_back(2);
//...
for_each(vw.begin(), vw.end(), [](int val)
{
cout << val << endl;
});

return 1;
}

They both do the same thing, they output the vector, but I don't think the second code looks better, I in fact think both examples need cleaning up, because to my eye they're miss leading, but my argument about the maintainability of Lambda's aside the second example does hint at the only use for them.  It hints that they can take the loop variable "val" as an input from the left, i.e. from the iteration over the vector in the "for_each" loop, rather than need to declare that iterator as in the first loop "auto itr = v.begin()"...

But I would still argue that this ease of throwing the code in there, leads to hard to maintain code, I think the first example cleaned up would leave a much more wholesome and maintainable code base...

#include <iostream>
#include <vector>

int main()
{
using namespace std;
vector<int> v = { 1, 2 };
for (auto itr = v.begin(); itr != v.end; ++itr)
{
cout << (*itr) << endl;
}
}

And there is my preferred implementation of that example, I find it simpler and easier to understand, and as you can see I'm using the C++11 declaration of the vector contents to ease understanding, so I'm not throwing an anti C++11 rant here, far from it, I've looked at Lambda's in Python and C# as well as here in C++ and I really don't like the syntax maintenance questions they bring up.

Sometimes they look and can behave very powerfully, but even with the for_each example above, I'd still much prefer this:

#include <iostream>
#include <vector>
#include <algorithm>

void Output (int p_Value)
{
std::cout << p_Value << std::endl;
}

int main ()
{
std::vector<int> v = { 1, 2 };
for_each (v.begin(), v.end(), Output);
}

I can see the "for_each" I can see it calls Output with each iteration, that code clearly has a semi-colon, and I can go find "Output" very easily.  I find this code is much cleaner and simpler to follow.