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

Sunday, 24 March 2019

C++ Variadic Template Parameter Packing Example

Today in the brief few mintues I hate, I wanted to welcome all the new readers the blog is getting, there are nearly 5000 of you folks passing through these pages each month!


And now the code video....

Today we go over a usage example for variadic templates, demonstrating the new C++17 parameter packing, how to call functions with the parameter pack, how to mix parameter types with the template and control the compilers iterative unrolling of your code.

Find the source code here:

Find Fedor Pikus's new book here:


Please Note: Filmed in one take, during the single half-hour I have spare, so don't complain about the low production values, cus the code does at least work!

Thursday, 3 November 2016

Software Engineering : Test Driven Development (TDD)

"Test-first fundamentalism is like abstinence-only sex ed:
An unrealistic, ineffective morality campaign for self-loathing and shaming."
 - David Heinemeier Hansson, 2014

I was very recently inflicted a case of TDD... I didn't like it, like the bad taste of medicine it lingered on my mind, so that I had to do some reading to even wrap my mind around the concept, and in wrapping around the idea my mind is made up to throttle it out of existence anywhere near me.

I come from the very much more formal days of development, from systems where you had very limited resources, there wasn't space to run a test suit on top of your editor next to your compiler, indeed the systems I learned to program with one had to chose to swap the editor and compiler and even a separate linker in and out of memory to achieve your build.

Taking that amount of time to do a build, it makes you learn from your mistakes quickly.  Such that I find myself now a rounded, and I'd like to think good, programmer.  I'm not the best, I've met a few of the best, but I'm good.

So combine a propensity to think about the problem and the drive to achieve a solution in code quickly, I'm used to thinking about testing after the fact, used to at least in part sticking to the old mantra of "Analyse -> Design -> Implement -> Test -> Document", with each step feeding each other.

For you see development today is not serial any more, you don't have time to stop and think, you perhaps should.  This was perhaps the only positive I see in employing TDD, and indeed it was one of the positives myself and the chap I was speaking to commonly came to, it makes you slow down and think about a problem.

However, if you're a traditional programmer, a goal orientated programmer, like myself, you've a plethora of patterns, design and experience to draw upon, which tell you your goal is achievable a certain way.

Design patterns and library implementation style, and simple rote learning of a path to a solution can drive development, peer review can share you ideas and impart new ideas on yourself, so why should you let the test; something which intrinsically feels like the end result, or the last step before accepting the solution; drive development of the solution?

I really can't think of a reason, and have now to take to the words of brighter stars than myself to express how it made me feel...

It felt like a litmus test, something being used to make me feel unprofessional, in a single trivial class, which should have taken five minutes to write and check over, an hours struggle ensued where hammer blow by hammer blow by the grace of TDD I was held up as a heretic.  "Thou dost not know TDD", the little voice in the back of my mind said, and I felt low.

But beyond how I felt, it seemed so inefficient to work in that manner, when one has programmed or engineered or done any task for long enough we build a reflect memory of how to achieve that task again, walking, reading, driving, programming... All these life goals and skills we just pick up.

Training in Karate was very much like this, one had to teach people to do things with care... 10 Print Hello 20 goto 10... Then we had to show them how to do more complex packaging and reuse of code procedure example(p_value : integer) and eventually we could let them free fight int main () { std::cout << "Hello World!" << std::endl; } and during this building up we let them drop the earlier teachings into their muscle memory, into their subconscious, we exercised, but didn't re-teach the same things, didn't cover the same ground.

Yet that coverage of the same ground is exactly where I felt TDD was taking me, and it seems to be the consensus among other "non believers" as to where it takes you, to write a test exercising your code, then to iterate over changes, sure it drives efficient code in the end, it drives out tested code before a single functional line has been written, but was it the quickest way to the same solution?

For a seasoned, experienced programmer like myself, No, No it was not, it bypassed so much of my experience as to know my self-confidence to literally brow beat me into worry.

I therefore stand and say "I do not write software test-first", and this is based on having to learn in an environment where one could not afford the processor cycles or memory to test, nor did one have bosses open to the concept of micro-design and iteratively pawing over code, one had to get the job done, and get it right or not have a role any longer.

Huib Schoots over at AgileRecord can be quoted as writing "TDD is a method of learning while writing clean, maintainable, highquality code", I would have to paraphrase that statement as "a method of learning today from scratch whilst writing modern, clean, maintainable, highquality code"  for a programmer setting out to learn their craft today is never going to have the benefit of the environment I learned in, they're not going to catch up to my twenty plus years of industry exposure and some thirty years academic experience on the topic.  They need to learn, and if teaching test proves a good starting point so be it, however, once the learning curve plateau is reached, even before, one has to question whether you need to take that next step back, step away from micromanaging the development process and evolving your code to just delivering the final product in a working form.*



Others on the topic:


http://beust.com/weblog/2014/05/11/the-pitfalls-of-test-driven-development/






* Please note, with this statement I am not advocating stagnation, and not saying that old-boys like myself are superior, however, TDD appears to me to dismiss any other way of working, to a fault and in my opinion its own ultimate flaw is itself, test your development, but don't drive your development with the test, you will seriously only be putting the cart before the horse.

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, 17 December 2013

Using the Singleton Pattern

We all know and love the singleton pattern, whereby you can ensure you only have one instantiated copy of a class, and can refer to that instance of the class at will?  Yes... Very useful for holding configuration if you're not totally familiar with the pattern.

In C++ we might have a singleton like this:

---- Singleton.hpp ----

#ifndef SINGLETON_CLASS
#define SINGLETON_CLASS

template <class C>
class Singleton
{

protected:
Singleton() {}
~Singleton() {}
private:
static C* s_Instance;
// Prevent copy
Singleton(Singleton&);
// Prevent assign
void operator=(Singleton&);

public:
inline static C& Instance()
{
if ( !s_Instance )
{
s_Instance = new C;
}
return *s_Instance;
}
inline static void DestroyInstance()
{
if ( s_Instance )
{
delete s_Instance;
s_Instance = NULL;
}
}
};

template <class C>
C* Singleton<C>::s_Instance = NULL;

#endif

----------

So this class gives us a basic singleton build into a class, so if we code:

-- Config.hpp --

#ifndef Config_CLASS
#define Config_CLASS

#include "Singleton.hpp"

#include <string>

// Forward declaration
class Config;

// Actual declaration
class Config : public Singleton<Config>
{
friend class Singleton<Config>;
private:
std::string m_Path;
/// Constructor is private
/// as the friend singleton
/// instantiates your class
/// with no params
Config ()
:
m_Path("C:\\HelloWorld")
{
}
public:
const std::string& Path()
{
return *m_Path;
}

};

#endif

-------------------

Nothing majorly wrong with this - I've not run this code through a compiler, to it just looks right and hopefully you get what I'm on about so far.

So our class derived from the singleton uses it, but each time we need to write a singleton we need to include this construction, and I've seen some people using macro's to replace that... so you might have:

#define SINGLETON_START (class_name) \
class class_name : public Singleton<class_name> \
{ \
friend class Singleton<class_name>;
And then:

#define SINGLETON_END() };

So forearmed we can now have our config look like this:

-- Config.hpp --

#ifndef Config_CLASS
#define Config_CLASS

#include "Singleton.hpp"

#include <string>

// Forward declaration
class Config;

SINGLETON_START(Config)
private:
std::string m_Path;
/// Constructor is private
/// as the friend singleton
/// instantiates your class
/// with no params
Config ()
:
m_Path("C:\\HelloWorld")
{
}
public:
const std::string& Path()
{
return *m_Path;
}

SINGLETON_END()

#endif

-------------------

Now, there's nothing wrong with this code-wise, its big crimes however are not obvious and in my opinion out way the benefit of using it.

So the benefits are the ease of declaring the inheritance and the friendship, it smooths that all out to a single line.

But the drawbacks, lets start with the plain text, code completion instantly breaks, it does not expand the Macro for the class definition.

Next, the physical act of using a Macro like this obfuscates away some code, and we're not talking about a trivial piece of maths we're talking about our class definition, so we instantly can't really use any of the decent document generators on our code, we could after using our own pre-processor to expand the macro ourselves, but its a real pain in the bum.

So this pattern is of use, and the macro can be of use, but using it is really a case of DO, or DO NOT... I'm on the DO NOT side, and I'll be adding this to my personal coding standards document soon.