Hello, and welcome to c++
weekly i'm your host, Jason Turner I am available for on-site training code reviews, and
contracting
Now this is our part three in our series of learning about modern a c++ and
Specifically, we are doing that, by, using the tools available i have visual studio set up with clang power tools
cppcheck and clang format extensions, i
Suggest that you go back, and watch the previous two episodes for what the series is about and my reasoning behind
Using, visual studio for these demonstrations so in this episode we're going to discuss some of the things that
we can, learn with our tools about inheritance and class hierarchies in
C++ in C++11 and moving forward so, we have here our?
Base class with a single pure virtual function, and we have our single data member and then
We have our function here called, do_thing() with the same name then this class struct
That inherits from base so let's go ahead
And save this and we're going to run, this through clean tidy and again remember
We have all of the settings turned on for claim to automatically apply fixes where it can, so the first thing that
We notice, is that clang-tidy, tells us the constructor
Does not initialize the data field and this is fairly important because
We actually, had code here that could have been operating on uninitialized data
This, primitive type of an int is not initialized
By default so this very simple
check
right here could theoretically catch many bugs in your code if you happen to have uninitialized data that you're operating on
The next thing that, we notice is our do_thing() function here?
actually is not
Overloading it is hiding the base class member do_thing() and
It is very possible that this is actually a bug in our code, where, we have unintentionally hidden
Base class functions, by changing the signature of them and then, we also see our parameter i is unused and
We get that it has commented out the name of i for us here so that it still has a name
But it is now no longer a quote unreferenced formal parameter as you
Would have gotten in an error from visual studios compiler. So let's go ahead and fix these things, we actually
Did intend to override not hide the base class member so let's just go ahead and remove this name altogether
And we like the fact that it is initializing using the uniform initialization syntax to the default
Value which is going to be zero in this case for an integer and let's go ahead and rerun our client id?
So, we can see here now that
clang-tidy has changed our method from being
Virtual to being override and this is great this actually
protects us from ourselves and i believe that
Is the only change it made and that is correct it used virtual it used override here instead of virtual now if we already go
Back to this previous version, where, we have some
integer in here
Let's just call it int for now because, we don't have a reason to name it now, we get from visual studio
Immediately an error telling us that, we have marked something override that is not actually overriding a
Base class member so we know that we've done something wrong this is the point of the override specifier to let us know that
We have done something
Incorrect when we intended to override but we're not actually overriding a
Base class member so this is the compiler in the tools protecting us from ourselves
Now, we haven't run, this through cppcheck in a, while let's go ahead and run cppcheck
And it does not yet have anything else to tell us
So, we have our struct, base, and derived here and now let's go ahead. And put in some code that initializes one of these
After all what is the point of having virtual functions if we're not going to be operating on these things through a base class pointer
So we've created our base class object. And we're calling our do_thing() member function on it and we'll rerun this through clang-tidy
now so clang-tidy is able to tell us we have a potential memory leak?
Here which is great it is true that, we do in fact have a potential memory leak, so we're going to
Also run, this through the visual studio compiler
and
We get no warnings there?
So to address our issue here we're going to add a delete then and hopefully this should have
Satisfied clang-tidy. Ah now it is telling us that, we are deleting an object called
Base that is abstract but has a non-virtual
Destructor and that is true so if we're going to do this correctly then, we need to add a virtual
destructor to our base class, and we'll do it like this and
Rerun our clang-tidy again.
So, we have seen that clang-tidy made a transformation for us here, we had code that looked
Like this and it made this equals default instead this is better because
it
More clearly tells us and the compiler that we're doing a default
Destruction were not trying to actually specify our own but then
we also get this warning that basically says we're not following the rule of
Five or rule of zero so this warning tells us we don't have our copy constructor copy assignment move assignment
So let's go ahead and do those
So, we created all of our special member functions and in the process created a, new problem for ourselves that
We no longer have a compiler created a default constructor
So, we will go ahead and specify that, also
So finally, we have it compiling
Again, without, any warnings now this is the kind of thing that falls into the category of lots of little
Gotchas, we didn't know, that, we needed to create a, virtual base class
Destructor but the compiler told us that and once we did it we didn't realize that, we had actually
Implicitly disabled our move operations, but the compiler told us that as, well or clang-tidy told us that as
Well so, we are able then to apply those and in the process we accidentally disabled our
Defaulted base class constructor and so, we were just had to explicitly default it and now this works
We have cleaned up all these problems and this is this is good this is what, we want so?
We don't have to necessarily be afraid of?
Accidentally leaving something out when, we are using the tools that can show
Us what exactly it is that we could have done better now the problem since i am going to point out, along the way?
Where the tools have failed us
Is that really in this example there's no reason to do dynamic memory allocation
At all and indeed if we were going to we should not have had a
New here we should have been using a unique pointer so let's go ahead, and make this a unique pointer and
we will include our memory header to do that and
Then here, we will say?
and
we no
Longer need delete and the visual studio ide tells us right away here that delete is meaningless
Will delete that because unique pointers doing automatic memory management for us and
Let's see what clang-tidy has to tell us now
So, we have gone ahead and made our unique pointer here and our tools are done giving us advice but really at this
Point, also a human reading this code
Have realized that we probably do not need?
to Be doing any dynamic allocation at all and and should be doing something like
this
But that is something that the tools are not really able to analyze yet and tell us that we are doing a dynamic allocation?
For no reason that is good so there you have it this wraps up
For the most part what our tools can currently, tell us about inheritance and
How to learn our again modern c++
Practices and remember the tools are always being updated and they will always be adding, new
Checks, that help us learn, these things, along the way?
Be sure to subscribe follow, me on twitter and check out, any of the links below