C++ -- how to initialize the static variable inside a member function? - c++

void ClassA::Func()
{
static map<int, string> mapIntStr;
mapIntStr[0] = m_memberVariable0; <= just want to do once & m_memberVariable* are not static
mapIntStr[1] = m_memberVariable1; <= just want to do once
...
}
I want to ONLY initialize the variable mapIntStr once. As we know, we can put the initialize code inside a static function and call that static function and store the return value into mapIntStr.
Here I would like to get a quick & dirty solution. As I remember, there is something called static scope. I would like to initialize mapIntStr ONCE without calling a static function. how can I do it?
Thank you

void ClassA::Func()
{
static map<int, string> mapIntStr;
if(mapIntStr.empty()){
mapIntStr[0] = m_memberVariable0;
mapIntStr[1] = m_memberVariable1;
// ...
}
}
How about that? :)
Edit
Well, the best solution would be to take the mapIntStr out of the function and into the class. And then you won't get around the static function call.
//in ClassA.h
class ClassA{
public:
void Func();
static map<int,string> InitStatic();
static map<int,string> mapIntStr;
};
//in ClassA.cpp
#include "ClassA.h"
void ClassA::Func(){
// use mapIntStr
}
map<int,string> ClassA::InitStatic(){
map<int,string> ret;
// init ret
return ret;
}
map<int,string> ClassA::mapIntStr = ClassA::InitStatic();
That're about the only options that I know of. So you've got the choice. Initialize the map once in the func or even in a contructor the first time a ClassA object is created (better version of the two) and live with the overhead of a nearly noop call to empty(), which will most likely be a single instruction only after proper inlining and will impose no overhead whatsoever, or use a static initialization function.

Create a inside struct, then initialize everything in the constructor of that struct, and then you declare a static variable of that struct.
void fun()
{
struct setter
{
setter(){}
};
static setter setup;
}
For your case:
void ClassA::Func()
{
struct Map : public std::map<int, string>
{
Map()
{
(*this)[0] = something;
(*this)[1] = somethingElse;
}
}
static Map map;
}

Related

Is it possible to use a static variable declared in another C++ library

I intend to use a library with a declaration of a variable in one of its function
/// in library A
function fun(){
static int iwanttouse = 1;
/// operation on iwanttouse
}
How can i use it in Application B? Do I connect it with extern
extern int iwanttouse;
// and then use it
if(iwanttouse == x)
.....
or I could use them without declaration?
No. Static variables have internal linkage, precisely so that you can't do that.
Don't use global variables, they make unit testing of your code next to impossible, use dependency injection instead.
Example:
#include <iostream>
// header file.
// Define a struct with all the data you need globally
struct my_data_t
{
bool i_want_house = true;
};
// Get a static instance
my_data_t& getGlobalData()
{
static my_data_t data;
return data;
};
// Put code where you want to use data in a class.
class my_class_t
{
public:
// constructor with dependency injection!
// this way any data can be injected (valuable for unit testing!)
explicit my_class_t(my_data_t& data) :
m_data{ data }
{
}
void show_i_want_house()
{
// use data
if (m_data.i_want_house)
{
std::cout << "I really want that house!\n";
}
else
{
std::cout << "Nah, this house is not good enough\n";
}
}
private:
my_data_t& m_data;
};
// cpp file
int main()
{
// instantiate objects with a reference to the data you want it to use.
my_class_t object_with_global_data{ getGlobalData() };
object_with_global_data.show_i_want_house();
my_data_t test_data{ false }; //aggregate initialization of struct
my_class_t object_with_test_data{ test_data }; //create an object with non-global data for testing
object_with_test_data.show_i_want_house();
return 0;
}
A variable marked with the keyword static(outside the class) is only visible to that translation unit. static elements are allocated storage only once in a program lifetime in static storage area. And they have a scope till the program lifetime.
So in your case, static int iwanttouse = 1; is not even seen by another translation unit. :)

Executing a specific function based on a std::string

I am trying to write a program that will execute a function based on a string I fetch from a database.
Basically what I do is:
// Create an enum
enum AFunc{
invalidFunction,
function2,
function3
}
// have a class handling the functions
struct A
{
static AFunc resolveStringToFunction(std::string) {...}
template<int T>
void execute(...)
{
// this may not be called = invalidFunction
}
template<>
void execute<1> (...)
{
// do stuff = function1
}
template<>
void execute<2> (...)
{
// do stuff = function2
}
};
In my application i do this:
A a;
std::string funcString = getFromDatabase (...) // Not really, but this is abstract
const AFunc funcType = A::resolveStringToFunction(funcString);
a.execute<funcType>(...);
The problem here is that the compiler does not accept the dynamic calling of a template function, because (as I understood it) it needs to know which function is called by compile time.
Is there any way around this?
Is there a better solution to this problem? Maybe a design pattern?
namespace afunc // dont pollute global namespace
{
typedef std::function<void(...)> aFunc;
static function1(...)
{
// do stuff
}
static function2(...)
{
// do stuff
}
const std::unordered_map<std::string, aFunc> functions (
{{"function1", &function1},{"function2", &function2}} ); // afunc
And it is called by the following code:
std::string funcString = getFromDatabase (...) // Not really, but this is abstract
afunc::functions.at(funcString)(...) // at because the map is const, so it's even threadsafe

C++: std::map<int,int> crashes when being assigned

I'm trying to make an int to int map but the program crashes and I don't realize why.
I've summarized the problem to this short simple code.
When the program starts, since the Utilities member _instance is static- it initialize it, by going to its constructor, which contain a single line: An int to int (simple) map assignment. but then it crashes.
Notice that if I comment that line, the program doesn't crash,
and that the main contains that very same line.
So my two questions are:
1) Why does it crash? is there a point behind this behavior?
2) How do I fix it so I can initialize the map at constructor?
Thank You
#include <map>
class Utilities
{
public:
~Utilities(){};
static Utilities& instance();
private:
Utilities();
Utilities( const Utilities& ){};
static Utilities _instance;
static std::map<int, int> textIntToIntMap;
};
Utilities Utilities::_instance = Utilities();
std::map<int, int> Utilities::textIntToIntMap;
Utilities::Utilities()
{
//The following line crashes, why?
textIntToIntMap[1] = 2;
}
int main()
{
static std::map<int, int> text2;
text2[4] = 2;
int xxx = 3;
}
You have an initialization order problem:
Utilities Utilities::_instance = Utilities();
This line calls the default constructor of Utilities, which then tries to populate the map. But the map is not initialized at this stage.
You should design your code to be robust against such initialization order issues. You can mitigate some of that by creating static instances inside functions. This gives you a handle on the ordering of initializations. But a simple re-ordering of the definitions should fix the immediate problem:
std::map<int, int> Utilities::textIntToIntMap;
Utilities Utilities::_instance = Utilities(); // OK, map has been defined
The issue is that you call the Utilities constructor before Utilities::textIntToIntMap has been constructed.
Swap the order of the following two lines:
Utilities Utilities::_instance = Utilities();
std::map<int, int> Utilities::textIntToIntMap;
Before initializing _instance you need to define map textIntToIntMap outside the class. Because in constructor you are using textIntToIntMap which is a static member so you need to define it first. So outside the class use following lines:
std::map<int, int> Utilities::textIntToIntMap;
Utilities Utilities::_instance = Utilities();
Others have already caught that the Utilities() are constructed before Utilities::textToIntMap. So, now the question is: how to avoid such problems in the future?
You can use a function returning a reference to a static local variable to ensure that the construction is done before the reference is used. You can put such function into a namespace. You should also have a convenience typedef with hopefully a shorter name, so that declaring iterators is not a finger-breaker on C++98. On C++11 you should be using auto anyway.
Note that the use of global or function-static non-POD data is not thread-safe in C++98. If you wish to safely use textToMap() from multiple threads, with no guarantee that it was accessed before the 2nd thread was started, textToIntMap would need to wrap the initialization within a mutex. To get a rough idea how this might be done, see the inner function from Qt's convenient Q_GLOBAL_STATIC.
The use of a singleton class seems like a pointless Java-ism in this case.
Run a test on ideone.
// Utilities.h
namespace Utilities {
typedef std::map<int, int> Map;
Map & textToIntMap();
}
// Utilities.cpp
namespace Utilities {
namespace {
struct InitializedMap : Map {
InitializedMap() {
insert(value_type(1, 2));
// or
(*this)[1] = 2;
}
};
}
Map & textToIntMap() {
static InitializedMap map;
return map;
}
}
Try this way::
#include <map>
#include <iostream>
using namespace std;
class Utilities
{
public:
static Utilities& instance() {
static Utilities instance;
return instance;
}
~Utilities(){};
void PrintMapValues();
void AddKeyValue(int key, int value);
private:
Utilities();
Utilities( const Utilities& ){};
std::map<int, int> int_to_int_map_;
};
Utilities::Utilities()
{
//The following line crashes, why?
int_to_int_map_[-99] = 2;
}
void Utilities::PrintMapValues() {
for(std::map<int, int>::iterator it = int_to_int_map_.begin(); it != int_to_int_map_.end(); ++it){
cout << "Key:" << it->first << " Val:" << it->second << endl;
}
}
void Utilities::AddKeyValue(int key, int value) {
int_to_int_map_[key] = value;
}
int main()
{
Utilities& utils = Utilities::instance();
for (int i=0; i< 10; i++) {
utils.AddKeyValue(i, i+20);
}
utils.PrintMapValues();
return 0;
}

C++ Assign a const value at run-time?

I have a constant value that never changes during run-time, but is impossible to know until run-time.
Is there a way to declare a constant (either as a member of a class or not) without defining it and also assign a computed value once (and only once) it is determined; or am I going to have to resort to a non-const declaration and use coding S & Ps (ALL_CAPS variables names, static declaration if in a class, etc.) to try and keep it from changing?
CLARIFICATION:
Though these are good answers, the real-world situation I have is more complicated:
The program has a main loop that continually runs between processing and rendering; the user can set required options and once they are set they will never change until the program is restart. An "Initialize" function is set up for anything that can be determined before the main loop, but values that are dependent on user interaction must be performed in the middle of the loop during the processing phase. (At the moment, persistent data storage techniques come to mind...)
Something like this?
const int x = calcConstant();
If it's a class member, then use the constructor initialisation list, as in Yuushi's answer.
You can define it in a struct or class and utilize an initialisation list:
#include <iostream>
struct has_const_member
{
const int x;
has_const_member(int x_)
: x(x_)
{ }
};
int main()
{
int foo = 0;
std::cin >> foo;
has_const_member h(foo);
std::cout << h.x << "\n";
return 0;
}
As a static or function-local variable:
const int x = calcConstant();
As a class member:
struct ConstContainer {
ConstContainer(int x) : x(x) {}
const int x;
};
Yes, you can make a private static singleton field with an initialization method and a gettor method. Here's an example of how to do it:
// In foo.h
class Foo
{
public:
// Caller must ensure that initializeGlobalValue
// was already called.
static int getGlobalValue() {
if (!initialized) {
... handle the error ...
}
return global_value;
}
static void initializeGlobalValue(...)
private:
static bool initialized;
static int global_value;
};
// In foo.cpp
bool Foo::initialized = false;
int Foo::global_value;
void Foo::initializeGlobalValue(...) {
if (initialized) {
...handle the error...
}
global_value = ...;
initialized = true;
}

Static function needing to deal with members of a C++ class

I have to make some kind of bridge between two pieces of software, but am facing an issue I don't know how to deal with. Hopefully someone will have interesting and (preferably) working suggestions.
Here is the background : I have a C++ software suite. I have to replace some function within a given class with another function, which is ok. The problem is that the new function calls another function which has to be static, but has to deal with members of the class. This is this second function which is making me mad.
If the function is not static I get the following error :
error: argument of type ‘void (MyClass::)(…)’ does not match ‘void (*)(…)’
If I set it to static I get either the following error :
error: cannot call member function ‘void
MyClass::MyFunction(const double *)’ without object
or
error: ‘this’ is unavailable for static member functions
depending on if I use or not the "this" keyword ("Function()" or "this->Function()").
And finally, the class object requires some arguments which I cannot pass to the static function (I cannot modify the static function prototype), which prevents me to create a new instance within the static function itself.
How would you deal with such a case with minimal rewriting ?
Edit : Ok, here is a simplified sample on what I have to do, hoping it is clear and correct :
// This function is called by another class on an instance of MyClass
MyClass::BigFunction()
{
…
// Call of a function from an external piece of code,
// which prototype I cannot change
XFunction(fcn, some more args);
…
}
// This function has to be static and I cannot change its prototype,
// for it to be passed to XFunction. XFunction makes iterations on it
// changing parameters (likelihood maximization) which do not appear
// on this sample
void MyClass::fcn(some args, typeN& result)
{
// doesn't work because fcn is static
result = SomeComputation();
// doesn't work, for the same reason
result = this->SomeComputation();
// doesn't work either, because MyClass has many parameters
// which have to be set
MyClass *tmp = new MyClass();
result = tmp->SomeComputation();
}
Pointers to non-static member functions are a bit tricky to deal with. The simplest workaround would just be to add an opaque pointer argument to your function which you can then cast as a pointer to 'this', then do what you need with it.
Here's a very simple example:
void doSomething(int (*callback)(void *usrPtr), void *usrPtr)
{
// Do stuff...
int value = callback(usrPtr);
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(myCallback, this);
}
private:
int value_;
static int myCallback(void *usrPtr)
{
MyClass *parent = static_cast<MyClass *>(usrPtr);
return parent->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
In this example myCallback() can access the private value_ through the opaque pointer.
If you want a more C++-like approach you could look into using Boost.Function and Boost.Bind which allow you to pass non-static member functions as callbacks:
void doSomething(boost::function<int ()> callback)
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(boost::bind(&MyClass::myCallback, this));
}
private:
int value_;
int myCallback()
{
return value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
If you really can't change the function prototype you could use a global pointer, but that opens up all sorts of issues if you will ever have more than one instance of your class. It's just generally bad practice.
class MyClass;
static MyClass *myClass;
void doSomething(int (*callback)())
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
myClass = this;
doSomething(myCallback);
}
private:
int value_;
static int myCallback()
{
return myClass->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
Following spencercw's suggestion below the initial question I tried the "static member variable that you set to point to this" solution (the global variable would have been tricky and dangerous within the context of the software suite).
Actually I figured out there was already something like this implemented in the code (which I didn't write) :
static void* currentObject;
So I just used it, as
((MyClass*)currentObject)->SomeComputation();
It does work, thanks !!!
non-reentrant and non-thread-safe way is to pass "this" address using global variable.
You can move the result = SomeComputation(); out of your static function and place it in BigFunction right before your call to the static function.