Reusing objects in functions defined in C++ header - c++

I have a function library in a header file, which includes the following function:
// Get a normally distributed float value in the range [0,1].
inline float GetNormDistrFloat()
{
std::random_device _RandomDevice;
std::normal_distribution<float> _NormalDistr(0.5, 2.0);
float val = -1;
do { val = _NormalDistr(_RandomDevice); } while(val < 0.0f || val > 1.0f);
return val;
}
This works well, however, I don't want to create the std::random_device and std::normal_distribution objects every time I call this function GetNormDistrFloat().
What is the "best" (correct) way in C++ to deal with this? I tried to just move those two object definitions outside the function, but that led to linker errors. Do I have to create a .cpp file for this header and initialize the objects there?

You could mark them as static variables which makes them behave almost like globals but only accessible inside the function:
void bar() {
static Foo foo_instance;
// Foo gets initialized only once
}
The main difference is the initialization. Globals get initialized at startup and static variables at their first access.
You can also make them globals, just make sure you do not define them in a header file, instead declare them as external:
// Header file
extern Foo foo_instance;
// Cpp file
Foo foo_instance;
Initialization of local static objects is thread-safe, however everything else is not.

I'm am not a fan of other solutions mentioned here; such as using globals or static locals. For one, state in functions is not a good idea as it's implicit and not obvious when reading code. It also makes things more complicated if you want to use the function from multiple threads. And it also makes testing more complicated. Instead, the "correct" way to handle state is to do the boring thing and create a class:
class NormDistrFloatGenerator
{
public:
NormDistFloatGenerator(const std::random_device& device,
const std::normal_distribution<float>& normal)
: m_device(device)
, m_normal(normal)
{}
float get_float() { // use member variables with same logic as in question }
private:
std::random_device m_device;
std::normal_distribution<float> m_normal;
};
At least if you write this class, you can test it properly, or use it in multiple threads. You only have to initialize this class once, and then you can repeatedly generate floats. If you really want to have something convenient, you can then do:
NormDistFloatGenerator& void makeGlobalFloatGenerator() {
static NormDistFloatGenerator(std::random_device, std::normal_distribution<float>(0.5, 2.0);
}
// at namespace scope
auto& g_float_generator = makeGlobalFloatGenerator();
You can then use g_float_generator everywhere. I'd really encourage you to avoid this approach. And even more so avoid the shortcuts others are suggesting.

Related

How do I assign to a const variable using an out parameter in C++?

In a class header file Texture.h I declare a static const int.
static const int MAX_TEXTURE_SLOTS;
In Texture.cpp I define the variable as 0.
const int Texture::MAX_TEXTURE_SLOTS = 0;
Now in Window.cpp class's constructor I attempt to assign to the variable using an out parameter, however this obviously does not compile as &Texture::MAX_TEXTURE_SLOTS points to a const int* and not an int* .
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &Texture::MAX_TEXTURE_SLOTS);
I have tried using const_cast, but am greeted with a segmentation fault on runtime.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, const_cast<int*>(&Texture::MAX_TEXTURE_SLOTS));
I have also tried directly casting to an int * but once again, seg fault.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int*)&Texture::MAX_TEXTURE_SLOTS);
Many thanks.
EDIT 2: So since you're trying to abstract OpenGL contexts, you'll have to let go of the "traditional" constructor/destructor idioms. And just for your information (unrelated to this question): OpenGL contexts are not tied to windows! As long as a set of windows and OpenGL contexts are compatible with each other, you may mix and match any way you like. But I digress.
The standard idiom to deal with a situation like yours is to use preinitializing factory functions. Like this:
class MyOpenGLContextWrapper {
public:
// Yes, shared_ptr; using a unique_ptr here for objects that are kind
// of a nexus for other things -- like an OpenGL context -- just creates
// a lot of pain and misery. Trust me, I know what I'm talkink about.
typedef std::shared_ptr<MyOpenGLContextWrapper> ptr;
struct constdata {
NativeGLContextType context;
// ...
GLint max_texture_image_units;
// ...
};
static ptr create();
protected:
MyOpenGLContextWrapper(constdata const &cdata) : c(cdata) {};
virtual ~MyOpenGLContextWrapper();
constdata const c;
}
MyOpenGLContextWrapper::ptr MyOpenGLContextWrapper::create()
{
struct object : public MyOpenGLContextWrapper {
object(MyOpenGLContextWrapper::constdata const &cdata) : MyOpenGLContextWrapper(cdata) {}
~object(){}
};
MyOpenGLContextWrapper::constdata cdata = {};
// of course this should all also do error checking and failure rollbacks
cdata.context = create_opengl_context();
bind_opengl_context(cdata.context);
// ...
glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS, &cdata.max_texture_image_units);
return std::make_shared<object>(cdata);
}
EDIT: I just saw that you intend to use this to hold on to a OpenGL limit. In that case you can't do this on a global scope anyway, since those values depend on the OpenGL context in use. A process may have several OpenGL contexts, each with different limits.
On most computer systems you'll encounter these days, variables declared const in global scope will be placed in memory that has been marked as read only. You literally can't assign to such a variable.
The usual approach to implement global scope runtime constants is by means of query functions that will return from an internal or otherwise concealed or protected value. Like
// header.h
int runtime_constant();
#define RUNTIME_CONSTANT runtime_constant()
// implementation.c / .cpp
int runtime_constant_query(){
static int x = 0;
// NOTE: This is not thread safe!
if( !x ){ x = determine_value(); }
return x;
}
You can then fetch the value by calling that function.
Provided that glGetIntegerv doesn't depend on other gl* functions being called before, you may use an immediately-invoked lambda:
// Texture.cpp
const int Texture::MAX_TEXTURE_SLOTS = []
{
int maxTextureSlots{0}:
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureSlots);
return maxTextureSlots;
}();
You don't.
You can't assign to a const outside of its definition. Also, using a const variable where the const has been const_casted away is UB. This also means you can't directly initialize a const variable with an output parameter. For trivial types, just output to another variable and make a const copy if you so wish.
If you were the author of the function you're calling, you would do well not to use out parameters, and then you could assign to const variables directly, perhaps using structured bindings if you want to name multiple of the outputs at a time. But here, you're not.

Conditionally create an object in c++

I am writing a program that has the option to visualize the output of an algorithm I am working on - this is done by changing a const bool VISUALIZE_OUTPUT variable defined in a header file. In the main file, I want to have this kind of pattern:
if(VISUALIZE_OUTPUT) {
VisualizerObject vis_object;
}
...
if(VISUALIZE_OUTPUT) {
vis_object.initscene(objects_here);
}
...
if(VISUALIZE_OUTPUT) {
vis_object.drawScene(objects_here);
}
However, this clearly won't compile since vis_object goes out of scope. I don't want to declare the object before the condition since it is a big object and it needs to available for multiple points in the code (I can't just have one conditional statement where everything is done).
What is the preferred way of doing this?
Declare the object on the heap and refer to it by using a pointer (or
unique_ptr)?
Declare the object on the heap and make a reference to it
since it won't ever change?
Some other alternative?
A reference will not be useable here, because at declaration it should refere to an already existing object, and live in a scope englobing all your if(VISUALIZE_OUTPUT). Long story short, the object will have to be created unconditionally.
So IMHO a simple way would be to create it on the heap and use it through a pointer - do not forget do delete it when done. The good point is that the pointer could be initialized to nullptr, and so it could be unconditionnaly deleted.
But I think that the best way would be to encapsulate everything in an object created in highest scope. This object would then contain methods to create, use internally and finally destroy the actual vis_object. That way, if you do not need it, nothing will be actually instanciated, but the main procedure will not be cluttered with raw pointer processing.
I would use Null_object_pattern:
struct IVisualizerObject
{
virtual ~IVisualizerObject() = default;
virtual void initscene(Object&) = 0;
virtual void drawScene(Object&) = 0;
// ...
};
struct NullVisualizerObject : IVisualizerObject
{
void initscene(Object&) override { /* Empty */ }
void drawScene(Object&) override { /* Empty */}
// ...
};
struct VisualizerObject : IVisualizerObject
{
void initscene(Object& o) override { /*Implementation*/}
void drawScene(Object& o) override { /*Implementation*/}
// ...
};
And finally:
std::unique_ptr<IVisualizerObject> vis_object;
if (VISUALIZE_OUTPUT) {
vis_object = std::make_unique<VisualizerObject>();
} else {
vis_object = std::make_unique<NullVisualizer>();
}
// ...
vis_object->initscene(objects_here);
//...
vis_object->drawScene(objects_here);
I'll give a few options. All have upsides and downsides.
If it is NOT possible to modify VisualizerObject, as I noted in comments, the effect could be achieved by using the preprocessor, since the preprocessor does not respect scope, and the question specifically seeks controlling lifetime of an object in a manner that crosses scope boundaries.
#ifdef VISUALIZE_OUTPUT
VisualizerObject vis_object;
#endif
#ifdef VISUALIZE_OUTPUT
vis_object.initscene(objects_here);
#endif
The compiler will diagnose any usage of vis_object that are not in #ifdef/#endif.
The big criticism, of course, is that use of the preprocessor is considered poor practice in C++. The advantage is that the approach can be used even if it is not possible to modify the VisualizerObject class (e.g. because it is in a third-party library without source code provided).
However, this is the only option that has the feature requested by the OP of object lifetime crossing scope boundaries.
If it is possible to modify the VisualizerObject class, make it a template with two specialisations
template<bool visualise> struct VisualizerObject
{
// implement all member functions required to do nothing and have no members
VisualizerObject() {};
void initscene(types_here) {};
};
template<> struct VisualizerObject<true> // heavyweight implementation with lots of members
{
VisualizerObject(): heavy1(), heavy2() {};
void initscene(types_here) { expensive_operations_here();};
HeavyWeight1 heavy1;
HeavyWeight2 heavy2;
};
int main()
{
VisualizerObject<VISUALIZE_OUTPUT> vis_object;
...
vis_object.initscene(objects_here);
...
vis_object.drawScene(objects_here);
}
The above will work in all C++ versions. Essentially, it works by either instantiating a lightweight object with member functions that do nothing, or instantiating the heavyweight version.
It would also be possible to use the above approach to wrap a VisualizerObject.
template<bool visualise> VisualizerWrapper
{
// implement all required member functions to do nothing
// don't supply any members either
}
template<> VisualizerWrapper<true>
{
VisualizerWrapper() : object() {};
// implement all member functions as forwarders
void initscene(types_here) { object.initscene(types_here);};
VisualizerObject object;
}
int main()
{
VisualizerWrapper<VISUALIZE_OUTPUT> vis_object;
...
vis_object.initscene(objects_here);
...
vis_object.drawScene(objects_here);
}
The disadvantage of both of the template approaches is maintenance - when adding a member function to one class (template specialisation) it is necessary to add a function with the same signature to the other. In large team settings, it is likely that testing/building will be mostly done with one setting of VISUALIZE_OUTPUT or the other - so it is easy to get one version out of alignment (different interface) to the other. Problems of that (e.g. a failed build on changing the setting) are likely to emerge at inconvenient times - such as when there is a tight deadline to deliver a different version of the product.
Pedantically, the other downside of the template options is that they don't comply with the desired "kind of pattern" i.e. the if is not required in
if(VISUALIZE_OUTPUT)
{
vis_object.initscene(objects_here);
}
and object lifetimes do not cross scope boundaries.

How can I initialize class variables in a header?

I'm writing a library where the user can define arbitrary structures and pass them to my library, which will then obtain the memory layout of the structure from a static member such structure must have as a convention.
For example:
struct CubeVertex {
// This is, per convention, required in each structure to describe itself
static const VertexElement Elements[];
float x, y, z;
float u, v;
};
const VertexElement CubeVertex::Elements[] = {
VertexElement("Position", VertexElementType::Float3),
VertexElement("TextureCoordinates", VertexElementType::Float2),
};
C++ best practices would suggest that I move the static variable and its initialization into my source (.cpp) file. I, however, want to keep the variable initialization as close to the structure as possible since whenever the structure changes, the variable has to be updated as well.
Is there a portable (= MSVC + GCC at least) way to declare such a variable inside the header file without causing ambiguous symbol / redefinition errors from the linker?
Consider a simple getter.
struct CubeVertex {
static const std::array<VertexElement, N>& GetElements() {
static const std::array<VertexElement, N> result = {
//..
};
return result;
}
//..
}
Immediate benefit: No array-to-pointer-decay.
What you could do here is using an anonymous namespace.
Wrap everything into "namespace { ... };" and you can then access CubeVertex::Elements like you normally do.
However, this creates a new instance of the static data everytime you include the headerfile, which adds to the executable's filesize.
It also has some limitations on how to use the class/struct, because you cannot call functions of that class from another file (which won't be a problem in this special case here).

Is it ok to use a static variable to initialize/register variables?

Language: C++
Toolkit: Qt4
The toolkit I'm using has a static method called int QEvent::registerEventType() to register my own event types. When I subclass this QEvent I need to supply the base class this value. QEvent::QEvent(int type).
Is it ok to use a static variable to call this before application starts? Consider the following:
//This is all in my .cpp file
static int myEventType; //This will contain my registered type
/*If I create a static instance of this class the constructor
gets called before the main() function starts.
*/
class DoRegisterMyEventType {
public:
DoRegisterMyEventType() {
myEventType = QEvent::registerEventType();
}
};
static DoRegisterMyEventType doRegisterMyEventType;
//Here is the constructor for MyEvent class which inherits QEvent.
MyEvent::MyEvent()
: QEvent(myEventType)
{
}
How 'evil' is this? I could wrap the whole thing in a namespace to prevent polluting the global namespace.
Since C++'s initialization across TUs is a big grey area with much implementation leeway, I prefer to scrap it completely and be explicit about what gets done when. (This rejection of initialization order due to lack of guarantees is similar to how singleton classes reject global objects.) Specifically, this means any global state (global variables, static data members, and function-local statics) that cannot be initialized with constant-expressions must be initialized in exactly one TU, and that TU is the one that implements main.
In the manual case, this means inserting and updating code in the translation unit that contains main and in main itself. The most common example of such code is calling srand(time(0)) to seed the std::rand PRNG.
You can refactor that manual code management using the preprocessor:
// the implementation file for main, could be named main.cpp
#include "whatever_declares_the_real_main.hpp"
#include "global_objects.inc"
int main(int argc, char* argv[]) try {
#include "main_init.inc"
return the_real_main(argc, argv);
// main.cpp has well-defined responsibility:
// initialize global state before passing control to another function, and
// handle return-code or exceptions
// you can modify this, depending on your preference and desired API
// for example:
return the_real_main(std::vector<std::string>(argv+1, argv+argc));
return the_real_main(parse_args(argv+1, argv+argc));
// just make sure to keep main.cpp's responsibility well-defined and
// relatively simple
}
// example handling; depending on your specifics, you might do something
// different, or know how to provide more information:
catch (std::exception& e) {
std::cerr << "abnormal termination: " << e.what() << '\n';
return 1;
}
catch (...) {
std::cerr << "abnormal termination.\n";
return 1;
}
These .inc files are neither headers nor implementation files. The exact file extension doesn't matter as long as you don't use something which is commonly used for headers or implementation files, such as .h, .hpp, .cc, .cpp, and so forth. You can generate global_objects.inc and main_init.inc based off file-naming conventions, using include guards so that dependencies may be included (just as include guards work for headers).
For example, both of these files correspond with myevent.hpp and would be placed alongside that header:
// file "myevent.global_inc"
#ifndef INCLUDE_GUARD_37E6F5857F8F47918A7C83F29A9DA868
#define INCLUDE_GUARD_37E6F5857F8F47918A7C83F29A9DA868
#include <QEvent.hpp> // or whatever headers you need
#include "myevent.hpp" // declares the variable defined just below
// (remember you use 'extern' to declare objects without defining them)
int your_namespace::myEventType = QEvent::registerEventType();
#endif
// file "myevent.main_inc"
#ifndef INCLUDE_GUARD_4F1B93D0F4D3402B802CBA433241AA81
#define INCLUDE_GUARD_4F1B93D0F4D3402B802CBA433241AA81
// nothing needed in this case, from what you've shown so far
// this is where you place expressions that would otherwise require a dummy
// global variable to make sure they are executed, but this also allows use
// of temporary variables while includes handle dependency order:
#include "something_else.main_inc" // fake example dependency, which must
{ // be executed first
int temp;
some_func(&temp);
other_func(temp); // not easy to transform this into a global's init
// expression, yet defining it this way is natural, because it's exactly
// how you would do it inside a function
}
#endif
Note that if you only require static data initialization with constant-expressions, then that is preferred over all other techniques. The primary restriction for that initialization is not being able to make a function call (but it's actually more complex), so it doesn't apply in your case; this is the only kind of global variable initialization that C can do, if you want to find out more.
Static level initialization is a huge compiler-dependent grey area, as others have mentioned. However, function level initialization is not a grey area and can be used to your advantage.
static inline int GetMyEventType()
{
static int sEventType = QEvent::registerEventType();
return sEventType;
}
MyEvent::MyEvent()
: QEvent(GetMyEventType())
{
}
This solution has the property that registerEventType is guaranteed to be called before you need your event type even if you construct MyEvent during static initialization, which is good, but it does open you up to thread-safety issues if it's possible for MyEvent to be constructed on multiple threads.
Here's a thread-safe version, based on boost::call_once:
#include "boost/thread/once.hpp"
static boost::once_flag sHaveRegistered = BOOST_ONCE_INIT; //This is initialized statically, effectively at compile time.
static int sEventType = -1; //-1 is not a valid event
static void DoRegister()
{
sEventType = QEvent::registerEventType();
}
static inline int GetMyEventType()
{
boost::call_once(sHaveRegistered, &DoRegister);
return sEventType;
}
I use the "static register object" pattern quite a bit, but you must be aware of one big problem - you must ensure that the thing you are registering with, which itself is likely to be static, is created before the thing you are registering. As C++ does not guarantee the order of static construction between translation units, this can be problematic. One solution is to use the so called Meyer Singleton:
class Registry {
public:
static Registry & Instance() {
static Registry r;
return r;
}
...
private:
Registry() {
...
}
};
As all references to the Registry must go through the Instance() method, you are guaranteed the required construction order.

Static vs. member variable

For debugging, I would like to add some counter variables to my class. But it would be nice to do it without changing the header to cause much recompiling.
If Ive understood the keyword correctly, the following two snippets would be quite identical. Assuming of course that there is only one instance.
class FooA
{
public:
FooA() : count(0) {}
~FooA() {}
void update()
{
++count;
}
private:
int count;
};
vs.
class FooB
{
public:
FooB() {}
~FooB() {}
void update()
{
static int count = 0;
++count;
}
};
In FooA, count can be accessed anywhere within the class, and also bloats the header, as the variable should be removed when not needed anymore.
In FooB, the variable is only visible within the one function where it exists. Easy to remove later. The only drawback I can think of is the fact that FooB's count is shared among all instances of the class, but thats not a problem in my case.
Is this correct use of the keyword? I assume that once count is created in FooB, it stays created and is not re-initialized to zero every call to update.
Are there any other caveats or headsup I should be aware of?
Edit: After being notified that this would cause problems in multithreaded environments, I clarify that my codebase is singlethreaded.
Your assumptions about static function variables are correct. If you access this from multiple threads, it may not be correct. Consider using InterlockedIncrement().
What you really want, for your long term C++ toolbox is a threadsafe, general purpose debug counters class that allows you to drop it in anywhere and use it, and be accessible from anywhere else to print it. If your code is performance sensitive, you probably want it to automatically do nothing in non-debug builds.
The interface for such a class would probably look like:
class Counters {
public:
// Counters singleton request pattern.
// Counters::get()["my-counter"]++;
static Counters& get() {
if (!_counters) _counters = new Counters();
}
// Bad idea if you want to deal with multithreaded things.
// If you do, either provide an Increment(int inc_by); function instead of this,
// or return some sort of atomic counter instead of an int.
int& operator[](const string& key) {
if (__DEBUG__) {
return _counter_map.operator[](key);
} else {
return _bogus;
}
}
// you have to deal with exposing iteration support.
private:
Counters() {}
// Kill copy and operator=
void Counters(const Counters&);
Counters& operator=(const Counters&);
// Singleton member.
static Counters* _counters;
// Map to store the counters.
std::map<string, int> _counter_map;
// Bogus counter for opt builds.
int _bogus;
};
Once you have this, you can drop it in at will wherever you want in your .cpp file by calling:
void Foo::update() {
// Leave this in permanently, it will automatically get killed in OPT.
Counters::get()["update-counter"]++;
}
And in your main, if you have built in iteration support, you do:
int main(...) {
...
for (Counters::const_iterator i = Counters::get().begin(); i != Countes::get().end(); ++i) {
cout << i.first << ": " << i.second;
}
...
}
Creating the counters class is somewhat heavy weight, but if you are doing a bunch of cpp coding, you may find it useful to write once and then be able to just link it in as part of any lib.
The major problems with static variables occur when they are used together with multi-threading. If your app is single-threaded, what you are doing is quite correct.
What I usually do in this situation is to put count in a anonymous namespace in the source file for the class. This means that you can add/remove the variable at will, it can can used anywhere in the file, and there is no chance of a name conflict. It does have the drawback that it can only be used in functions in the source file, not inlined functions in the header file, but I think that is what you want.
In file FooC.cpp
namespace {
int count=0;
}
void FooC::update()
{
++count;
}