Related
Is it possible to initialize a static const member of my class during run-time? This variable is a constant throughout my program but I want to send it as a command-line argument.
//A.h
class A {
public:
static const int T;
};
//in main method
int main(int argc,char** argv)
{
//how can I do something like
A::T = atoi(argv[1]);
}
If this cannot be done, what is the type of variable I should use? I need to initialize it at run-time as well as preserve the constant property.
You cannot rely on data produced after your main has started for initialization of static variables, because static initialization in the translation unit of main happens before main gets control, and static initialization in other translation units may happen before or after static initialization of main translation unit in unspecified order.
However, you can initialize a hidden non-const variable, and provide a const reference to it, like this:
struct A {
public:
// Expose T as a const reference to int
static const int& T;
};
//in main.cpp
// Make a hidden variable for the actual value
static int actualT;
// Initialize A::T to reference the hidden variable
const int& A::T(actualT);
int main(int argc,char** argv) {
// Set the hidden variable
actualT = atoi(argv[1]);
// Now the publicly visible variable A::T has the correct value
cout << A::T << endl;
}
Demo.
I am sorry to disagree with the comments and answers saying that it is not possible for a static const symbol to be initialized at program startup rather than at compile time.
Actually this IS possible, and I used it many times, BUT I initialize it from a configuration file. Something like:
// GetConfig is a function that fetches values from a configuration file
const int Param1 = GetConfig("Param1");
const int MyClass::Member1 = GetConfig("MyClass.Member1");
As you see, these static consts are not necessarily known at compile time. They can be set from the environment, such as a config file.
On the other hand, setting them from argv[], seems very difficult, if ever feasible, because when main() starts, static symbols are already initialized.
No, you cannot do that.
If this cannot be done what is the type of variable I should use ?
You can use a non-const member.
class A
{
public:
static int T;
};
int A::T;
Another option is to make T a private member, make main a friend so only it can modify the value, and then expose the member through a function.
#include <cstdlib>
class A
{
public:
static int getT() { return T; }
private:
static int T;
friend int main(int argc, char** argv);
};
int A::T;
int main(int argc, char** argv)
{
A::T = std::atoi(argv[1]);
return 0;
}
Not only you can't, you should not try doing this by messing with const_cast. Static const members have a very high chance of ending up in read-only segment, and any attempt to modify them will cause program to crash.
Typically you will have more than one configuration value. So put them in a struct, and the normal global access to it is const.
const config* Config;
...
main (int argc, char* argv [])
{
Config= new config (argc, argv);
...
}
You can get fancier and have a global function to return config, so normal code can't even change the pointer, but it is harder to do that by accident.
A header file exposes get_config () for all to use, but the way to set it is only known to the code that's meant to do so.
No, since you defined the variable as static and const, you cannot change its value.
You will have to set its value in the definition itself, or through a constructor called when you create an object of class A.
Method #1: Initialize a hidden non-const variable, and provide a const reference to it (as shown by dasblinkenlight):
class A {
public:
static const int &T;
};
static int dummy = 0;
const int &A::T = dummy;
int main() {
dummy = 10;
std::cout << A::T << std::endl;
}
Live Demo
Method #2: Use a non const static member (as shown by R Sahu):
class A {
public:
static int T;
};
int A::T = 0;
int main() {
A::T = 10;
}
Live Demo
Method #3: Declare a hidden non-const variable as a private static member of your class and provide a static member const reference to interface it. Define a friend function as inititalizer:
class A {
friend void foo(int);
static int dummy;
public:
static const int &T;
};
const int &A::T = A::dummy;
int A::dummy = 0;
void foo(int val) { A::dummy = val; }
int main() {
foo(10);
std::cout << A::T << std::endl;
}
Live Demo
Method #4: Declare a hidden non-const variable as a private static member of your class and provide a static member const reference to interface it. Define a static member function as inititalizer:
class A {
static int dummy;
public:
static const int &T;
static void foo(int val) { A::dummy = val; }
};
const int &A::T = A::dummy;
int A::dummy = 0;
int main() {
A::foo(10);
std::cout << A::T << std::endl;
}
Live Demo
Bonus:
If you want to initialize only once you can change the helper function to:
static void foo(int val) {
static bool init = true;
if(init) A::dummy = val;
init = false;
}
Live Demo
Having been facing the same problem myself lately I found #A.S.H 's answer to be the closest to perfect but the fact that the variables have to be initialized so early can cause some problems:
Can't use data sources that aren't available yet, such as argc and argv as per the question.
Some dependencies might not be initialized yet. For example, many a GUI framework does not allow creating textboxes that early on yet. This is a problem because we might want to display a error textbox if loading the configuration file fails to inform the user.
So I came up with the following:
template <class T>
class StaticConfig
{
public:
StaticConfig()
{
if (!mIsInitialised)
{
throw std::runtime_error("Tried to construct uninitialised StaticConfig!");
}
}
const T*
operator -> () const
{
return &mConfig;
}
private:
friend class ConfigHandler;
StaticConfig(const T& config)
{
mConfig = config;
mIsInitialised = true;
}
static T mConfig;
static bool mIsInitialised;
};
template <class T>
T StaticConfig<T>::mConfig;
template <class T>
bool StaticConfig<T>::mIsInitialised = false;
We make our data static but non-const so we don't have to initialize it immediately and can assign the correct values to it at a more opportune time. Read only access is given trough a overload of operator -> The default constructor checks if a StaticConfig of this type has already been loaded with valid data and throws if it is not. This should never happen in practice but serves as a debugging aid. A private constructor allows loading the type with valid data. A ConfigHandler class, responsible for loading the data, is made a friend so it can access the private constructor.
A ConfigHandler instance can be briefly created at an opportune time when all the dependencies are available to initialize all the StaticConfig types. Once done, the ConfigHandler instance can be discarded. After that, a class can simply include the appropriate type of StaticConfig as a member and read-only access the data with minimal intrusion.
Online demonstration.
N - O
The semantics of what is being required are all wrong, and you shouldn't use a static-const for that.
A static is an object or integral type which has static storage duration and internal linkage.
A const is an object that does not change its value throughout application's lifetime, any attempt to change it results in UD . ( the overwhelming majority of such cases is a pretty well defined crash )
As a result of this question dangerous workarounds have been proposed to mimic the implied behavior. In most of examples a static-const-reference is given a somehow hidden static which is assignable at runtime, e.g. this.
Apart from the difficulties in maintaining such code, the problem remains that declared semantics are not actually enforced.
For example in keeping the value const throughout the application runtime can be hacked by doing const_cast<int &>(A::T) = 42 , which is perfectly valid, perfectly define code since the referenced type is not const.
What is being sought after here is an class that permits to be initialized only once throughout the application, has internal linkage, and the lifetime of the application.
So just do a template class that does that:
template<typename V> class fixation
{
bool init = true;
V val;
public:
fixation(V const & v) : init(true), val(v) {}
fixation & operator=( fixation arg)
{
if(init )
{
this->val = arg.val;
}
this->init = false;
return *this;
}
V get()
{
return val;
}
};
struct A
{
static fixation<int> T;
};
How to handle the case that it is called a second time, that is an implementation decision. In this example the value is totally ignored. Others may prefer to throw an exception, do an assertion, ... etc.
There is a trick, but you should probably avoid it! Here's a bare bones example to illustrate the principle:
int const& foo(int i) {
static const int j = (i == 0 ? throw 0 : i);
return j;
}
int main() {
try {
int x = foo(0); // oops, we throw
} catch(...) {}
int x = foo(1); // initialized..
int y = foo(0); // still works..
}
Careful!
Use a Singleton Pattern here.
have a data member which you'd like to initialize at run time in the singleton class. One a single instance is created and the data member is properly initialized, there would be no further risk of overwriting it and altering it.
Singleton would preserve the singularity of your data.
Hope this helps.
I have this code which I have written so I can atomically write a float and int together, as 64 bits:
namespace X{
template<typename P>
class MyClass<P>{
public:
MyCompStruct getStruct(){
return MyCompStruct; // Is this correct?
}
private:
float a;
struct MyCompStruct{
union{
struct{
float b;
int32_t c;
};
uint64_t composite;
};
operator=(const MyCompStruct& src) {
this->composite= src.composite;
}
};
};
}
but I am struggling how I declare so that I can grab the struct from a different class with ao object of type MyClass:
X::MyClass<P>::MyCompStruct mcs = obj.getStruct(); // Completely wrong
mcs.b = ...
mcs.c = ...
Could somebody please help?
There are several problems with your code
MyCompStruct is defined using template specialization syntax. Get rid of the extra <P>.
MyCompStruct is declared private so only MyClass and friends of MyClass can access it. If you want others to access MyCompStruct you need to make it public (or protected if you want to limit access to derived classes).
MyCompStruct is declared after its first use in getStruct. Declare it before it's used.
Your assignment operator has no return type and returns no data. This is wrong.
getStruct is attempting to return a type instead of an instance of a type. You need to add some parenthesis in there.
Stop using using namespace std;. It's just bad form. it's not in the code you posted but I can smell it.
getStruct doesn't appear to be a function that would make any modifications to the object. Declaring it const would be good for your soul.
Here is your code with all of the fixes for the issues noted above.I removed the namespace because it's irrelevant here.
template<typename P>
class MyClass // Removed extra <P>
{
public: // Make it public
// Decalre before it's usage.
struct MyCompStruct
{
union{
struct{
float b;
int32_t c;
}; // Unnamed unions are a non-standard. Be careful.
uint64_t composite;
};
// Added a return type
MyCompStruct& operator = (const MyCompStruct& src)
{
composite = src.composite;
// Returning this allows operations to be chained a = x = y;
return *this;
}
};
MyCompStruct getStruct() const
{
return MyCompStruct(); // Return an instance instead of a type
}
private:
float a;
};
Basic usage:
int main()
{
MyClass<int> obj;
MyClass<int>::MyCompStruct mcs = obj.getStruct();
}
Now that all of that has been fixed you have a couple of options for getStruct.
In the version above it returns a newly created instance of MyCompStruct. If all you want/need is access to the type itself and all getStruct does is create an empty instance you can get rid of getStruct completely and allow others to directly create an instance of MyCompStruct.
int main()
{
MyClass<int>::MyCompStruct mcs;
}
If this is not the behavior you want and you would rather return a reference or pointer to an already created instance owned (as a member variable) by MyClass you can change it like below
template<typename P>
class MyClass
{
public:
/**** Removed unchanged code ****/
// Return a non-const reference allowing others to modify the
// contents of compData. If you don't want others to MODIFY the data
// change the return type to const MyCompStruct&
MyCompStruct& getStruct()
{
return compData; // Return our owned instance
}
// Return a const reference to compData. This prevents others
// from modifying the data and allows them to access it with a
// const qualified instance of MyClass.
const MyCompStruct& getStruct() const
{
return compData; // Return our owned instance
}
private:
MyCompStruct compData;
};
I've the following utility function to convert a given string to integer.
class convertToInt:public std::unary_function<const char*, int>
{
public:
int operator()(const char* cNumber)
{
try
{
int result = boost::lexical_cast<int>(cNumber);
return result;
} catch ( boost::bad_lexical_cast& error)
{
std::cerr << "Error in converting to number "<< error.what() << std::endl;
return -1;
}
}
};
When I want to actually use this utility function, I've to do the following.
convertToInt cStrToInt;
int iNumberToCheck = cStrToInt(argv[1]);
I'm just wondering, is there a way, I can directly call
int iNumberToCheck = convertToInt(argv[1]);
No, it is a member function and requires an object for it to be invoked on. You could use an unnamed temporary instead:
int iNumberToCheck = convertToInt()(argv[1]);
You can make the function static, so that it does not require an instance. The call has to be scoped.
You can also create the temporary as part of your larger expression (rather than using a named variable), which may seem less efficient but in practice is probably optimized to the same thing by your compiler.
Edit to add: static won't work for operator(), so you would need to rework to use that option.
If you know the name of the functor at the call-site, then you why not just turn it into a function?
int convertToInt(const char* cNumber)
{
/*...*/
}
int iNumberToCheck = convertToInt(argv[1]);
Just create a statically-initialized global variable, which helps avoid the static initialization order fiasco. Static initialization requires the class to be an aggregate type. Just use the braces to initialize it:
struct convertToIntF
{
int operator()(const char* cNumber) const
{
try
{
int result = boost::lexical_cast<int>(cNumber);
return result;
}
catch ( boost::bad_lexical_cast& error)
{
std::cerr << "Error in converting to number "<< error.what() << std::endl;
return -1;
}
}
};
convetToIntF converToInt = {};
Now, if the function object stores state or inherits from a class that is not an aggregate, this won't work. However, in C++11, its fairly trivial to write an adaptor that can static initialize any default constructible function object:
template<class F>
struct static_
{
template<class... T>
auto operator()(T && ... x) const -> decltype(F()(std::forward<T>(x)...))
{
static F f;
return f(std::forward<T>(x)...);
}
};
Then it can be initialized like this:
static_<convetToIntF> converToInt = {};
In this very simple case, an anonymous object will probably work fine, as others have pointed out. If you have a more complex class with state, however, consider the singleton pattern:
class SingletonFunctor
{
private:
// some private state
// for a hybrid approach, the constructor could be public
SingletonFunctor()
{
// initialize state
}
public:
static const SingletonFunctor& GetSingleton()
{
static const SingletonFunctor _singleton;
return _singleton;
}
SomeType operator() (SomeOtherType param) const
{
// do something interesting
}
};
int main (void)
{
SomeType firstVal = SingletonFunctor::GetSingleton()(SomeOtherType());
// ...
// later
// no need to instantiate another object
SomeType secondVal = SingletonFunctor::GetSingleton()(SomeOtherType());
}
Be careful with this pattern if you mutate state, it can then have all the same problems as a global variable (especially with multithreading).
I have code like this...
class Time
{
public:
Time(int, int, int);
void set_hours(int);
void set_minutes(int);
void set_seconds(int);
int get_hours() const;
int get_minutes() const;
int get_seconds() const;
static void fun() ;
void printu() const;
void prints();
private:
int x;
int hours;
int minutes;
int seconds;
const int i;
};
Why do I need to put const at last to make a function constant type but if i need to make a function, I can do this like...
static void Time::fun()
{
cout<<"hello";
}
Above function fun() is also in same class. I just want to know what is the reason behind this?
with a const instance method such as int get_hours() const;, the const means that the definition of int get_hours() const; will not modify this.
with a static method such as static void fun();, const does not apply because this is not available.
you can access a static method from the class or instance because of its visibility. more specifically, you cannot call instance methods or access instance variables (e.g. x, hours) from the static method because there is not an instance.
class t_classname {
public:
static void S() { this->x = 1; } // << error. this is not available in static method
void s() { this->x = 1; } // << ok
void t() const { this->x = 1; } // << error. cannot change state in const method
static void U() { t_classname a; a.x = 1; } // << ok to create an instance and use it in a static method
void v() const { S(); U(); } // << ok. static method is visible to this and does not mutate this.
private:
int a;
};
The const in the end means the function is constant, so it doesn't change the object's state.
When you put the const in the end, you can't change the state of the object's members.
Declaring a function static means it doesn't belong to the object at all, it belongs to the class type.
Putting const in the beginning means the return type value is a constant.
When you put const at the beginning, you're applying it to the return type. This doesn't matter if you're return type if void, but lets say you're returning char* that is not const. If you put const at the beginning, you'd end up with
static const char* MyFunction() { ... }
That tells me that the return type is a const char*, not a const function that returns a char*.
Putting it at the end avoids this problem.
It is because that if you put the const first it would mean that you are returning a const thing from the function - i.e. a different meaning that the function is const
It's a purely grammatical issue. const is a cv-qualifier and, when applied to a member function, must be placed after the parameter declarations. It you attempted to place it before the function name it could only be interpreted as qualifying the return type of the function.
static, on the other hand, is a storage class specifier and must appear before the declarator to which it applies.
These rules just flow from the way the C++ grammar is defined.
It is because that if you put the const first it would mean that you are returning a const thing from the function
One and another is explained a bit more in detail here. Putting const after a function declaration makes the function constant, meaning it cannot alter anything in the object that contains the function.
I'd like to map string to an instance member functions, and store each mapping in the map.
What is the clean way of doing something like that?
class MyClass
{
//........
virtual double GetX();
virtual double GetSomethingElse();
virtual double GetT();
virtual double GetRR();
//........
};
class Processor
{
private:
typedef double (MyClass::*MemFuncGetter)();
static map<std::string, MemFuncGetter> descrToFuncMap;
public:
static void Initialize();
void Process(Myclass m, string);
};
void Processor::Initialize()
{
descrToFuncMap["X"]=&MyClass::GetX;
descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse;
descrToFuncMap["RR"]=&MyClass::GetRR;
descrToFuncMap["T"]=&MyClass::GetT;
};
void Processor::Process(MyClass ms, const std::string& key)
{
map<std::string, Getter>::iterator found=descrToFuncMap.find(key);
if(found!=descrToFuncMap.end())
{
MemFuncGetter memFunc=found->second;
double dResult=(ms).*memFunc();
std::cout<<"Command="<<key<<", and result="<<result<<std::end;
}
}
let me know if you see a problem with this approach and what are common idioms for that?
Perhaps, I should use if-else-if statement chain, given that I have a limited number of member functions, instead of a confusing map of func pointers
BTW, I found some of the useful info here in the c++-faq-lite
Looks fine to me, but for the fact that descrToFuncMap needs to be declared static if you intend to initialise it from inside the static function Initialize().
If you want to make sure that Initialize() gets called, and gets called just once, you can use the Singleton pattern. Basically, if you aren't doing multithreading, that just means wrapping descrToFuncMap inside its own class (called say FuncMap) with a private constructor that calls Initialize(). Then you add a static local variable of type FuncMap to Processor::Process() -- because the variable is static, it persists and is only initialised once.
Example code (I now realise that friend isn't really necessary here):
class Processor {
private:
typedef double (MyClass::*MemFuncGetter)();
class FuncMap {
public:
FuncMap() {
descrToFuncMap["X"]=&MyClass::GetX;
descrToFuncMap["SomethingElse"]=&MyClass::GetSomethingElse;
descrToFuncMap["RR"]=&MyClass::GetRR;
descrToFuncMap["T"]=&MyClass::GetT;
}
// Of course you could encapsulate this, but its hardly worth
// the bother since the whole class is private anyway.
map<std::string, MemFuncGetter> descrToFuncMap;
};
public:
void Process(Myclass m, string);
};
void Processor::Process(MyClass ms, const std::string& key) {
static FuncMap fm; // Only gets initialised on first call
map<std::string, Getter>::iterator found=fm.descrToFuncMap.find(key);
if(found!=fm.descrToFuncMap.end()) {
MemFuncGetter memFunc=found->second;
double dResult=(ms).*memFunc();
std::cout<<"Command="<<key<<", and result="<<result<<std::end;
}
}
This is not the "true" Singleton pattern as different functions could create their own, separate instances of FuncMap, but it's enough for what you need. For "true" Singleton, you would declare FuncMap's constructor private and add a static method, say getInstance(), which defined the one-and-only instance as a static variable and returned a reference to that. Processor::Process() would then use this with
FuncMap& fm = FuncMap::getInstance();
I'd change
void Processor::Process(MyClass ms, std::string key)
to
void Processor::Process(const MyClass& ms, const std::string& key)
Don't see any bad side effect for now. Probably with boost::function as a map value it will be easier in the future.
Avoid using 'virtual' if you are using maps of function pointers. In this context, using 'virtual' keyword will not help much. For example
descrToFuncMap["X"]=&MyClass::GetX;
will always call 'MyClass::GetX' function even if GetX is overridden by the derived class of MyClass.
Usually you won't have large number of functions in class, rather than using map you can create simple struct array and use a for loop. If the number of functions are small, there won't be any big performance difference in map and array. Something similar to code below will work
class MyClass
{
//........
double GetX();
double GetSomethingElse();
double GetT();
double GetRR();
//........
};
typedef double (MyClass::*MemFuncGetter)();
struct FuncTable
{
const char* m_pFuncName;
MemFuncGetter m_pFuncPtr;
};
class Processor
{
public:
void Process(Myclass& m, string);
};
static FuncTable descrToFuncMap[]
{
{ "X", &MyClass::GetX},
{ "SomethingElse", &MyClass::GetSomethingElse },
{ "RR", &MyClass::GetRR},
{ "T", &MyClass::GetT}
};
void Processor::Process(MyClass& ms, const std::string& key)
{
int functablesize = sizeof(descrToFuncMap)/sizeof(descrToFuncMap[0])
for(int i=0; i< functablesize; ++i)
{
if( strcmp(key.c_str(), descrToFuncMap[i].m_pFuncName)==0)
{
MemFuncGetter memFunc=descrToFuncMap[i].m_pFuncPtr;
double dResult=(ms).*memFunc();
std::cout<<"Command="<<key<<"result="<<result<<std::end;
break;
}
}
}