I need to instantiate many objects from a class, but each one of them needs to be aware of a certain value X that is common for every object of this class, like a global parameter. This is necessary for my constructors to work properly in my objects.
Is there a way to do that without passing the value as a constructor parameter? What I wanna do is use the same variable in all objects so I don't waste RAM.
*in my real situation it's not just an X value, is a 1024-dimmension int vector.
What you want is a static member. "When a data member is declared as static, only one copy of the data is maintained for all objects of the class". e.g.
class myClass {
public:
static int x;
};
I assume you mean that you want a vector of size 1024 as the shared variable across all your classes. You could do this:
class MyClass {
static std::vector<int> s_my_vector;
}
This code would go into your header file. In your cpp file, you'd have to initialize the std::vector. However, I do not recommend this. Class static variables that require constructor calls (i.e. not primitives or POD types) have a lot of gotchas that I'm not planning to go into. I will offer a better solution however:
class MyClass {
static std::vector<int> & GetMyVector()
{
static std::vector<int> my_vector;
static bool initialized = MyVectorInit(my_vector);
return my_vector;
}
static bool MyVectorInit(std::vector<int> & v)
{
v.resize(1024);
...
}
public:
MyClass() {
std::vector<int> & v = GetMyVector();
...
}
static void EarlyVectorInit()
{
GetMyVector();
}
}
In this case, the static local variable ensures that there will only be one copy of my_vector, and you can get a reference to it by calling GetMyVector. Furthermore, the static bool initialized is guaranteed to only be created once, which means that MyVectorInit will only be called once. You can use this method in case you need to populate your vector in some non-trivial way that can't be done in the constructor.
The way I've written it, your vector will be created automatically the first time you need to use it, which is fairly convenient. If you want to manually trigger creation for some reason, call EarlyVectorInit().
Related
Given the class:
class A {
Public:
void foo() {
static int i;
i++;
}
};
How would you change it to prevent i from changing between instances following this example:
A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 1
o3.foo(); // i = 1
o1.foo(); // i = 2
i.e. allocate memory for i on every instance.
EDIT:
Yes, you can add i as an instance variable, but what if you need these counters in various (independent) functions ? I am looking to limit the scope of the variable only to the function ("in member functions"). It would seem awkward to add variables such as i, c, counter, counter_2 to the class if you need various counters, would it not ?
class A
{
public:
int i = 0;
void foo(){
++i;
}
};
is the normal way: i is now a member variable of the class. Clearly you don't want to use static.
In circumstances where declaring data members become costly(need for sparse members that are not used so often), An instance indepent collection - normally an associative one - may come in handy. Knowing nothing more about the OP's intention, std::map family of classes can be used as first speculation. We need to have one counter per visited object in A::foo, but not for unvisited instances(i.e. A instances not calling A::foo). This was the the simplest first solution I came up with:
void A::foo(){
static std::map<A*,std::size_t> i;
++i[this];
//...
};
Upon call to std::map::operator[] on an object not in the map, the associated value is default constructed in a memory location already zeroed by the allocator( in short words 1st-timers are automatically initialized to 0).
I have class like this:
class result{
public:
int a;
int b;
int c;
};
a,b,c can be filled with any integer. However, there is some famous cases which I will use them too much like for example the zero case where (a=b=c=0) or the identity case where (a=b=c=1) and some others.
So I want an easy way to get this instances when I want one of them without creating new object and filling it manually (the real case contains much more complex that 3 integers).
What I am doing currently is like this:
class result{
public:
int a;
int b;
int c;
static result get_zero(){
return result{0,0,0};
}
static result get_idenity(){
return result{1,1,1};
}
};
and in main:
auto id=result::get_identity();
Is this a good way to achieve what I want? Is there like an idiomatic way for doing this?
If the objects can be modified after you return them, then yes, this is the correct way, since you cannot share a single object.
NRVO (http://en.cppreference.com/w/cpp/language/copy_elision) and move-semantics remove any cost associated with returning the object by value.
If you know these objects will never be changed, you can return a result const & instead and have the object itself be a static member of your class. At that point, you don't even technically need the getter/setter, since the static members are public and already marked as const.
class result{
public:
int a;
int b;
int c;
static result const zero_result{0,0,0};
static result const & get_zero(){
return result::zero_result;
}
static result const identity_result{1,1,1};
static result const & get_idenity(){
return result::identity_result;
}
};
don't forget to allocate the memory for your static data members in a .cpp file, though:
result const result::zero_result;
result const result::identity_result;
Conventionally we would probably just create a static instance that you can re-use, copy from etc.
// someFile.h
extern const result ZERO, ID;
// someFile.cpp
const result ZERO{0, 0, 0};
const result ID{1,1,1};
Alternatively, have your class own these instances as static members and have your functions return a reference.
To be honest, though, your current approach seems perfectly performant and may be the most easy-to-use.
Your proposal solution it's strongly compiler optimization efficiency. Actually when result::get_identity(); is called a new result object is created and returned.
This will invoke the initialization constructor and, in the best case, the move constructor then.
Probably your compiler will optimize that with RVO.
One good approach it may be to create const static objects from your code can refer to.
For example in your class:
class Result {
// something
public:
static const Result Zero;
static const Result Identity;
};
// ... and then you can refer to it
do_something(Result::Zero);
In that way you can refer to object which will be created only once, when your program starts and avoid instantiating always a new notorious object.
you could make a static class of your result and use that. i did this for a product i made in c# and it worked perfectly
I'm making a game engine and I'm using libraries for various tasks. For example, I use FreeType which needs to be initialized, get the manager and after I don't use it I have to de-initialize it. Of course, it can only be initialized once and can only be de-initialized if it has been initialized.
What I came up with (just an example, not "real" code [but could be valid C++ code]):
class FreeTypeManager
{
private:
FreeTypeManager() {} // Can't be instantiated
static bool initialized;
static TF_Module * module; // I know, I have to declare this in a separate .cpp file and I do
public:
static void Initialize()
{
if (initialized) return;
initialized = true;
FT_Initialize();
FT_CreateModule(module);
}
static void Deinitialize()
{
if (!initialized) return;
initialized = false;
FT_DestroyModule(module);
FT_Deinit();
}
};
And for every manager I create (FreeType, AudioManager, EngineCore, DisplayManager) it's pretty much the same: no instances, just static stuff. I can see this could be a bad design practice to rewrite this skeleton every time. Maybe there's a better solution.
Would it be good to use singletons instead? Or is there a pattern suiting for my problem?
If you still want the singleton approach (which kind of makes sense for manager-type objects), then why not make it a proper singleton, and have a static get function that, if needed, creates the manager object, and have the managers (private) constructor handle the initialization and handle the deinitialization in the destructor (though manager-type objects typically have a lifetime of the whole program, so the destructor will only be called on program exit).
Something like
class FreeTypeManager
{
public:
static FreeTypeManager& get()
{
static FreeTypeManager manager;
return manager;
}
// Other public functions needed by the manager, to load fonts etc.
// Of course non-static
~FreeTypeManager()
{
// Whatever cleanup is needed
}
private:
FreeTypeManager()
{
// Whatever initialization is needed
}
// Whatever private functions and variables are needed
};
If you don't want a singleton, and only have static function in the class, you might as well use a namespace instead. For variables, put them in an anonymous namespace in the implementation (source) file. Or use an opaque structure pointer for the data (a variant of the pimpl idiom).
There's another solution, which isn't exactly singleton pattern, but very related.
class FreeTypeManager
{
public:
FreeTypeManager();
~FreeTypeManager();
};
class SomeOtherClass
{
public:
SomeOtherClass(FreeTypeManager &m) : m(m) {}
private:
FreeTypeManager &m;
};
int main() {
FreeTypeManager m;
...
SomeOtherClass c(m);
}
The solution is to keep it ordinary c++ class, but then just instantiate it at the beginning of main(). This moves initialisation/destruction to a little different place. You'll want to pass references to FreeTypeManager to every class that wants to use it via constructor parameter.
Note that it is important that you use main() instead of some other function; otherwise you get scoping problems which require some thinking how to handle..
What is the rationale for not having static constructor in C++?
If it were allowed, we would be initializing all the static members in it, at one place in a very organized way, as:
//illegal C++
class sample
{
public:
static int some_integer;
static std::vector<std::string> strings;
//illegal constructor!
static sample()
{
some_integer = 100;
strings.push_back("stack");
strings.push_back("overflow");
}
};
In the absense of static constructor, it's very difficult to have static vector, and populate it with values, as shown above. static constructor elegantly solves this problem. We could initialize static members in a very organized way.
So why doesn't' C++ have static constructor? After all, other languages (for example, C#) has static constructor!
Using the static initialization order problem as an excuse to not introducing this feature to the language is and always has been a matter of status quo - it wasn't introduced because it wasn't introduced and people keep thinking that initialization order was a reason not to introduce it, even if the order problem has a simple and very straightforward solution.
Initialization order, if people would have really wanted to tackle the problem, they would have had a very simple and straightforward solution:
//called before main()
int static_main() {
ClassFoo();
ClassBar();
}
with appropriate declarations:
class ClassFoo {
static int y;
ClassFoo() {
y = 1;
}
}
class ClassBar {
static int x;
ClassBar() {
x = ClassFoo::y+1;
}
}
So the answer is, there is no reason it isn't there, at least not a technical one.
This doesn't really make sense for c++ - classes are not first class objects (like in e.g. java).
A (static|anything) constructor implies something is constructed - and c++ classes aren't constructed, they just are.
You can easily achieve the same effect though:
//.h
struct Foo {
static std::vector<std::string> strings;
};
//.cpp
std::vector<std::string> Foo::strings(createStrings());
IMO there's just no need for one more syntactic way of doing this.
In which translation unit would the static objects be placed?
Once you account for the fact that statics have to be placed in one (and only one) TU, it's then not "very difficult" to go the rest of the way, and assign values to them in a function:
// .h
class sample
{
public:
static int some_integer;
static std::vector<std::string> strings;
};
//.cpp
// we'd need this anyway
int sample::some_integer;
std::vector<std::string> sample::strings;
// add this for complex setup
struct sample_init {
sample_init() {
sample::some_integer = 100;
sample::strings.push_back("stack");
sample::strings.push_back("overflow");
}
} x;
If you really want the code for sample_init to appear in the definition of class sample, then you could even put it there as a nested class. You just have to define the instance of it in the same place you define the statics (and after they've been initialized via their default constructors, otherwise of course you can't push_back anything).
C# was invented 15-20 years after C++ and has a completely different build model. It's not all that surprising that it offers different features, and that some things are less simple in C++ than in C#.
C++0x adds a features to make it easier to initialize vectors with some data, called "initializer lists"
You could get by with putting your "static" members in their own class with their own constructor that performs their initialization:
class StaticData
{
int some_integer;
std::vector<std::string> strings;
public:
StaticData()
{
some_integer = 100;
strings.push_back("stack");
strings.push_back("overflow");
}
}
class sample
{
static StaticData data;
public:
sample()
{
}
};
Your static data member is guaranteed to be initialized before you first try to access it. (Probably before main but not necessarily)
Static implies a function that is disassociated with an object. Since only objects are constructed, it is not apparent why a static constructor would have any benefit.
You can always hold an object in a static scope which has been constructed in a static block, but the constructor you would use would still be declared as non-static. There's no rule that indicates you can't call a non-static method from a static scope.
Finally, C++ / C defines the start of a program to be when the main function is entered. Static blocks are called prior to the entry of the main function as part of setting up the "environment" of the evaluated code. If your environment dictates full control over the set-up and tear-down, then it's easy to argue that it's not really some environmental fixture as much as an inherit procedural component of the program. I know that the last bit is sort of code-philosophy (and that it's rationale could be interpreted differently), but one shouldn't put critical code "before" the official start of an executable's handing off "full control" to the code written by the programmer.
This a question related to the initialization of objects in C++.
I have a group of classes (not instances), inheriting from a common base class, and I need them to register info about themselves in a container (specifically a map) when the program starts.
The problem is that I need it to be dynamic. The container is defined in an independent project, different from the classes. I would prefer to avoid making multiple hard-coded versions of the library, one for each set of classes in each program that uses it.
I thought about having a static instance of a special class in each of these subclasses, that would make the registration in its constructor. However, I have found no way to guarantee that the container will be constructed before the construction of these objects.
I should also note that the information in the container about the subclasses should be available before any instance of these subclasses is created.
Is there a way to do this, or imitate a static constructor in C++ in general?
You are describing different problems all at once. On the particular issue of having some sort of static initialization, a simple approach is creating a fake class that will perform the registration. Then each one of the different classes could have a static const X member, the member will have to be defined in a translation unit, and the definition will trigger the instantiation of the instance and the registration of the class.
This does not tackle the hard problem, which is the initailization order fiasco. The language does not provide any guarantee on the order of initialization of objects in different translation units. That is, if you compile three translation units with such classes, there is no guarantee on the relative order of execution of the fake member. That is also applied to the library: there is no guarantee that the container in which you want to register your classes has been initialized, if such container is a global/static member attribute.
If you have access to the code, you can modify the container code to use static local variables, and that will be a step forward as to ensure the order of initialization. As a sketch of a possible solution:
// registry lib
class registry { // basically a singleton
public:
static registry& instance() { // ensures initialization in the first call
static registry inst;
return inst;
}
// rest of the code
private:
registry(); // disable other code from constructing elements of this type
};
// register.h
struct register {
template <typename T>
register( std::string name ) {
registry::instance().register( name, T (*factory)() ); // or whatever you need to register
}
};
// a.h
class a {
public:
static a* factory();
private:
static const register r;
};
// a.cpp
const register a::r( "class a", a::factory );
// b.h/b.cpp similar to a.h/a.cpp
Now in this case there is no definite order among the registration of the a and b classes, but that might not be an issue. On the other hand, by using a local static variable in the registry::instance function the initialization of the singleton is guaranteed to be performed before any call to the registry::register methods (as part of the first call to the instance method).
If you cannot make that change you are basically out of luck and you cannot guarantee that the registry will be instantiated before the other static member attributes (or globals) in other translation units. If that is the case, then you will have to postpone the registration of the class to the first instantiation, and add code to the constructor of each class to be registered that ensures that the class is registered before actual construction of the object.
This might or not be a solution, depending on whether other code creates objects of the type or not. In the particular case of factory functions (first one that came to mind), if nothing else is allowed to create objects of types a or b... then piggy backing registration on constructor calls will not be a solution either.
This is a candidate for the Singleton pattern. Basically, you want the container to be instantiated when the first instance of a subclass is instantiated. This can be facilitated by checking if the singleton pointer is NULL in the base-class constructor, and if so, then instantiate the container.
One idea is to pass a registration functor to the classes. Each descendant would execute the function to register. This functor could be passed in the constructor.
Example:
struct Registration_Interface
{
virtual void operator() (const std::string& component_name) = 0;
};
struct Base
{
};
struct Child1
: public Base
{
Child(Registration_Interface& registration_ftor)
{
//...
registration_ftor("Child1");
}
};
See: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
One option is to construct the container lazily, when the first thing is added to it:
void AddToContainer(...) {
// Will be initialized the first time this function is called.
static Container* c = new Container();
c->Add(...);
}
The only way to "imitate" a static constructor is to explicitly call a function to perform your static initialization. There is no other way to run code pre-main just by linking in a module.
You might use an "initialise on first use" pattern, and then instantiate a dummy static instance to ensure initialisation as early as possible.
class cExample
{
public :
cExample() ;
// Static functions here
private :
static bool static_init ;
// other static members here
}
cExample::static init = false ;
cExample::cExample()
{
// Static initialisation on first use
if( !static_init )
{
// initialise static members
}
// Instance initialisation here (if needed)
}
// Dummy instance to force initialisation before main() (if necessary)
static cExample force_init ;
It is against OOP paradigm, but how about having your static members form a linked list guided by 2 global variables? You could do something like that:
ClassRegistrator *head = nullptr;
ClassRegistrator *tail = nullptr;
struct ClassRegistrator {
// ... Data that you need
ClassRegistrator *next;
ClassRegistrator(classData ...) {
if (!head)
head = tail = this;
else {
tail->next = this;
tail = this;
}
// ... Do other stuff that you need for registration
}
};
// The class you want to register
class MyClass {
static ClassRegistrator registrator;
}
ClassRegistrator MyClass::registrator(...); // Call the constructor
I believe the global variables, as they don't need have a constructor, but are just pure data, are guaranteed to be already initialised when you begin the execution of your code.
Obviously this is not thread-safe, etc, but should make your job done.