For example I have a following class:
class singelton
{
public:
static singelton* Instance()
{
if (m_pInstance == 0)
{
m_pInstance = new singelton();
}
return m_pInstance;
}
void setData(std::string input) { data = input; }
void getData() const { std::cout << data << std::endl; }
private:
singelton() {}
~singelton() {}
static singelton* m_pInstance;
std::string data;
};
typedef singelton s;
//what is this? Why need a singleton name? I mean "singelton*".
singelton* singelton::m_pInstance = 0;
int main(int argc, char** argv)
{
s.Instance()->setData("Something...");
s.Instance()->getData();
return 0;
}
What is singelton* singelton::m_pInstance = 0;?
This function assigns zero/null to a singleton instance, but why need use singleton* ? That assignment like a function, but use as assignment.
Static data members are not part of objects of a given class type; they are separate objects. As a result, the declaration of a static data member is not considered a definition. So static member must be defined outside of the class declaration.
In your example:
singelton * is a type of member.
singleton:: is class name (like namespace)
and m_pInstance is member name
P.S.: Because of static variables are initialised with 0 by default in C++, you don't need to explicitly set m_pInstance to 0 (or NULL). The definition only will be enough:
singelton * singelton::m_pInstance;
What is singelton* singelton::m_pInstance = 0;?
It's the initialiser for the static member variable m_pInstance, statically initialising the pointer to be null. singelton* (pointer to singelton) is the type of the variable; singlelton::m_pInstance is the (qualified) name of the variable; and = 0 is the initialiser.
This function assigns zero/null to a singleton instance, but why need use singleton* ?
No, it initialises the pointer to null; it doesn't point to anything yet. The object itself will be created, and the pointer updated to point to it, the first time someone calls Instance(). It's a pointer so that the object itself can be created when it's first needed, rather than at some arbitrary point during program startup - this is known as "lazy initialisation".
Beware that, in C++, there is no way to implement the Singleton anti-pattern correctly. This particular implementation has the problems of leaking the object, and not being thread-safe. I strongly recommend that you get rid of it: just instantiate the object in an appropriate place, with a lifetime that's longer than whatever uses it, and pass references to whatever needs it.
Use
Singleton::Instance()->setData("Hello");
and
Singleton::Instance()->getData();
The class can only have one instance - hence called singleton
And the Singleton::Instance gives you access to that
singelton* singelton::m_pInstance = 0;
Initializes it and when you first use it the singleton is created
Related
I've recently started working with C++ and I have stumbled across a problem that I cannot seem to understand.
class MyClass
{
bool eventActive = false;
static bool JoinCommand()
{
if (eventActive == true) // eventActive error: "a nonstatic member reference must be relative to a specific object"
{
// do something here...
}
else
{
}
};
I need JoinCommand to be static but I also need to use eventActive which is required to be non-static and is used/modified by other functions in the same class. Therefore I cannot make eventActive static because I will need to make it const aswell.
And the error:
"a nonstatic member reference must be relative to a specific object"
I guess I cannot create a new instance of MyClass. So how am I supposed to deal with this? Or is there anything wrong that I do not understand / I misunderstand? Any help will be greatly appreciated.
EDIT:
Thanks to everyone for helping me out on this one. I made my way through to what I wanted to achieve but learning new things I stumbled accross another problem that is kind of close to this one.
class Command
{
public:
const char * Name;
uint32 Permission;
bool (*Handler)(EmpH*, const char* args); // I do not want to change this by adding more arguments
};
class MyClass : public CommandScript
{
public:
MyClass() : CommandScript("listscript") { }
bool isActive = false;
Command* GetCommands() const
{
static Command commandtable[] =
{
{ "showlist", 3, &DoShowlistCommand } // Maybe handle that differently to fix the problem I've mentioned below?
};
return commandtable;
}
static bool DoShowlistCommand(EmpH * handler, const char * args)
{
// I need to use isActive here for IF statements but I cannot because
// DoShowlistCommand is static and isActive is not static.
// I cannot pass it as a parameter either because I do not want to
// change the structure of class Command at all
// Is there a way to do it?
}
};
A static member function of a class is by definition independent of the state of any non static member of the class. This means that you can use it without an object.
As soon as you rely on a non static member, your function has to be non static:
class MyClass
{
bool eventActive = false;
public:
bool JoinCommand() // non static, because
{
if (eventActive == true) // it depends clearly on the state of the object
{ /* do something here... */ }
}
};
You can then call your member function as expected:
MyClass omc;
if (omc.JoinCommand())
cout << "Command joined successfully"<<endl;
If you have nevertheless a valid reason to keep your function static:
The only way to access non static elements, in a static member function is to tell the function which object it has to use for getting access non statics (parameter, global object, etc...). Exacltly as you would do oustide the class.
Example:
class MyClass
{
bool eventActive = false;
public:
static bool JoinCommand(MyClass& omc) // example by provding a parameter
{
if (omc.eventActive == true) // access non static of that object
{ /* do something here... */ }
}
};
You would call it like this:
MyClass obj;
if (MyClass::JoinCommand(obj)) // a little bit clumsy, isn't it ?
...
If you actually want JoinCommand to be a static method, while eventActive is a non-static member, your only choice is to pass in the object to the method explicitly.
class MyClass
{
bool eventActive = false;
static bool JoinCommand(MyClass *object)
{
if (object->eventActive) // No error, since we are referencing through an object.
{
// do something here...
}
else
{
// Do something else here
}
}
};
Having a non-static member variable means that each instance of MyClass has an independent eventActive member, and that the value can be different for each instance. This second point means that something like "MyClass.eventActive" doesn't have any meaning. What if you have two instances of MyClass, and the value of eventActive is true in one and false in the other? Which value do you mean? If you're trying to make a class for which there can only be one instance, you might want to take a look at the singleton pattern. Even in that case though, JoinCommand would have to be non-static.
So I have a class with static variables, the reason they are static is for (while it may seem insignificant) efficiency (only being required to load once, reduce redundancy of storage in memory of the same file).
Anyway what I'd like to know, is there a way to check if a variable has been loaded?
Or is there a way to have a specific constructor called the first time an instance of this class is created and another used while other instances exist?
If neither of these are appropriate what is the solution?
If your static members are private, and initialized in the same translation unit as all of your class's member functions, then the standard guarantees that the static members will be initialized before they are used. See: When are static C++ class members initialized?
There are other situations where this guarantee does not help you (e.g. accessing non-private static members from another translation unit, or from inline member functions).
You can play games with isInitialized flags, but be aware that without further work this is not thread-safe.
The C++ FAQ recommends to wrap static class instances in functions, this ensures that they are initialized on first use. e.g.:
Fred& x()
{
static Fred* ans = new Fred();
return *ans;
}
Source: https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
Here you go:
class Test {
static bool isInitialized;
public:
Test() {
if (!isInitialized) {
// do whatever you need here
// ...
isInitialized = true;
}
}
};
bool Test::isInitialized = false;
You may do something like:
struct StaticData
{
// some variables
};
class YourClass
{
public:
YourClass(/*..*/) {
if (staticData == nullptr) {
staticData = std::make_unique<StaticData>(/*..*/)
}
}
private:
static std::unique_ptr<StaticData> staticData;
};
static std::unique_ptr<StaticData> YourClass::staticData;
The pointer-to-member feature of C++ is interesting and powerful, but I'm wondering if it is or should be limited only to instantiated objects of a class, or if it is okay to point to a static member? The use cases aren't obvious to me for either static or non-static usage of the feature, though it does seem very interesting.
Pointers to statics are actually "normal" pointers, e.g.
class MyClass
{
public:
static int x;
static int f(int a)
{
return a+1;
}
};
// ...
int* pint = &MyClass::x; // pointer to static property
int (*pfunc)(int) = &MyClass::f; // pointer to static method
Pointers to non-static members are "special" because they need a class instance to dereference a value. They can be thought of as "offset of a member inside a class instance" (this is very rough, though, and cannot be applied to method pointers!).
Static members, on contrast, are actually much like namespaced global variables, possibly with restricted visibility. They have static memory addresses, which are independent of class instances — all instances share a single static member.
The following is legal C++11 code.
struct X
{
static void f() {}
static int i;
X() = delete;
};
typedef void(*funcPtr)();
int main()
{
funcPtr g = &X::f;
int * j = &X::i;
}
There is nothing wrong about taking adresses of static member data and functions. As you can see the class never gets instantiated at any time.
If I have two static variables in different compilation units, then their initialization order is not defined. This lesson is well learned.
The question I have: are all the static variables already allocated, when the first one is being initialized. In other words:
static A global_a; // in compilation unit 1
static B global_b; // in compilation unit 2
struct A {
A() { b_ptr = &global_b; }
B *b_ptr;
void f() { b_ptr->do_something(); }
}
int main() {
global_a.f();
}
Will b_ptr point to a valid piece of memory, where B is allocated and initialized at the time of the execution of the main function? On all the platforms?
Longer story:
The compilation unit 1 is Qt library.
The other one is my application. I have couple QObject derived classes, that I need to be able to instantiate by the class name string. For this I came up with a templated factory class:
class AbstractFactory {
public:
virtual QObject *create() = 0;
static QMap<const QMetaObject *, AbstractFactory *> m_Map;
}
QMap<const QMetaObject *, AbstractFactory *> AbstractFactory::m_Map; //in .cpp
template <class T>
class ConcreteFactory: public AbstractFactory {
public:
ConcreteFactory() { AbstractFactory::m_Map[&T::staticMetaObject] = this; }
QObject *create() { return new T(); }
}
#define FACTORY(TYPE) static ConcreteFactory < TYPE > m_Factory;
Then I add this macro on every QObject subclass definition:
class Subclass : public QObject {
Q_OBJECT;
FACTORY(Subclass);
}
Finally I can instantiate a class by the type name:
QObject *create(const QString &type) {
foreach (const QMetaObect *meta, AbstractFactory::m_Map.keys() {
if (meta->className() == type) {
return AbstractFactory::m_Map[meta]->create();
}
}
return 0;
}
So the class gets a static QMetaObject instance: Subclass::staticMetaObject from the Qt library - it is auto-generated in Q_OBJECT macro I think. And then the FACTORY macro creates a static ConcreteFactory< Subclass > instance. ConcreteFactory in its constructor tries to reference of Subclass::staticMetaObject.
And I was pretty happy with this implementation on linux (gcc), until I compiled it with Visual Studio 2008. For some reason AbstractFactory::m_Map was empty on the runtime, and the debugger would not break at the factory constructor.
So this is where the smell of static vars referencing other static vars is coming from.
How can I optimize this code to avoid all these traps?
Yes, the standard allows this.
There are a number of paragraphs in section [basic.life] which start out
Before the lifetime of an object has
started but after the storage which
the object will occupy has been
allocated or, after the lifetime of an
object has ended and before the
storage which the object occupied is
reused or released, any pointer that
refers to the storage location where
the object will be or was located may
be used but only in limited ways.
and there is a footnote which indicates that this specifically applies to your situation
For example, before the construction of a global object of non-POD class type
Short Answer: Its should work as you have coded it. See Ben Voigt Answer
Long Answer:
Do something like this:
Rather than let the compiler decide when globals are created, create them via static methods (with static function variables). This means that they will be deterministically created on first use (and destroyed in the reverse order of creation).
Even if one global uses another during its construction using this method gurantees that they will be created in the order required and thus be available for usage by the other (watch out for loops).
struct A
{
// Rather than an explicit global use
// a static method thus creation of the value is on first use
// and not at all if you don't want it.
static A& getGlobalA()
{
static A instance; // created on first use (destroyed on application exit)
// ^^^^^^ Note the use of static here.
return instance; // return a reference.
}
private:
A()
:b_ref(B::getGlobalB()) // Do the same for B
{} // If B has not been created it will be
// created by this call, thus guaranteeing
// it is available for use by this object
}
B& b_ref;
public:
void f() { b_ref.do_something(); }
};
int main() {
a::getGlobalA().f();
}
Though a word of warning.
Globals are an indication of bad design.
Globals that depend on other globals is another code smell (especially during construction/destruction).
Yes. All are located in .data section, that is allocated at once (and it's not heap).
Putting it another way: if you are able to take its address, then it's OK, because it surely won't change.
If B has a constructor, like A has, then the order that they are called is undefined. So your code won't work unless you are lucky. But if B doesn't require any code to initialise it, then your code will work. It's not implementation-defined.
Ah, but the idea that static variables are "not initialised" is quite wrong. They're always initialised, just not necessarily with your initialiser. In particular, all static variables are created with value zero before any other initialisation. For class objects, the members are zero. Therefore global_a.b_ptr above will always be a valid pointer, initially NULL and later &global_b. The effect of this is that use of non-pointers is unspecified, not undefined, in particular this code is well defined (in C):
// unit 1
int a = b + 1;
// unit 2
int b = a + 1;
main ... printf("%d\n", a + b); // 3 for sure
The zero initialisation guarantee is used with this pattern:
int get_x() {
static int init;
static int x;
if(init) return x;
else { x = some_calc(); init = 1; return x; }
}
which assures either a non-return due to infinite recursion, or, correctly initialised value.
I'm developing a game which is based around the user controlling a ball which moves between areas on the screen. The 'map' for the screen is defined in the file ThreeDCubeGame.cpp:
char m_acMapData[MAP_WIDTH][MAP_HEIGHT];
The ThreeDCubeGame.cpp handles most of the stuff to do with the map, but the player (and keyboard input) is controlled by ThreeDCubePlayer.cpp. When a player moves into a new map cell, the game will have to check the contents of that cell and act accordingly. This function in ThreeDCubeGame.cpp is what I am trying to use:
inline char GetMapEntry( int iMapX, int iMapY ) { return m_acMapData[iMapX][iMapY]; }
So, in order to check whether the player is allowed to move into a map cell I use this function call from ThreeDCubePlayer.cpp:
if (ThreeDCubeGame::GetMapEntry(m_iMapX+MAP_OFF_X, m_iMapY+MAP_OFF_Y) == ' ')
{
// do stuff
}
But, when I compile this, I get the warning "error C2352: 'ThreeDCubeGame::GetMapEntry' : illegal call of non-static member function". Is this something to do with the scope of the variables? Is it fixable without redesigning all the code?
class A {
int i;
public:
A(): i(0) {}
int get() const { return i; }
};
int main() {
A a;
a.get(); // works
A::get(); // error C2352
}
There's no object to call the function with.
GetMapEntry is not static so you can't call it without an object of the type ThreeDCubeGame.
Alternatives:
-Make GetMapEntry static: static inline char GetMapEntry
-Create an instance of ThreeDCubeGame and do instance.GetMapEntry(
ThreeDCubeGame is a class, not an instance, thus you can only use it to access static members (that is, member function with the keyword static)
You have to instantiate an object of this class to use non-static members
ThreeDCubeGame map;
...
map.GetMapEntry(iMapX, iMapY).
You are trying to call a class method. Is that what you intend? Or do you mean for GetMapEntry to be an instance method? If it's a class method, it needs to be marked static. If it's an instance method, you need to call it with an instance of ThreeDCubeGame. Also, is GetMapEntry even a member of a class?
The error indicates that your are calling the GetMapEntry function as a static one whereas you have declare it as a member function. You need to:
call it via an instance of ThreeDCubeGame: threedcubegameinstance.GetMapEntry(),
declare the GetMapEntry function as static (add a static before inline and make m_acMapData static too).
You're missing the "static" keyword.
// .h
class Playfield
{
public:
static char GetTile( int x, int y );
// static on a method means no 'this' is involved
};
// .cpp
static char tiles[10][10] = {};
// static on vars in .cpp prevents access from outside this .cpp
char Playfield::GetTile( int x, int y )
{
// handle invalid args
// return tile
return tiles[x][y];
}
There's other options if you want only one unique playfield:
You can make Playfield a singleton, turn it into a namespace or use global functions.
The result is the same from the caller's point of view.
On a side note:
Since all of these use a static and/or global variable it's inherently not thread-safe.
If you require multiple playfields and/or want to play safe with multi-threadding and/or want to absolutely do it in an OOP fashion, you will need an instance of Playfield to call the function on (the 'this' pointer):
class Playfield
{
public:
char GetTile( int x, int y ) const { return this->tiles[x][y]; }
// you can omit 'this->', but it's inherently present because
// the method is not marked as static
public:
Playfield()
{ /*you will have to initialize 'this->tiles' here because
you cannot use the struct initializer '= {}' on member vars*/ }
private:
char tiles[10][10];
};
The calling code would use Playfield like this:
void main()
{
// static version
char tile11 = Playfield::GetTile( 1, 1 );
// non-static version
Playfield myPlayfield;
char tile12 = myPlayfield.GetTile( 1, 2 );
}
It can be useful to have a class containing a collection of functions, without any data members, if you don't want to expose the helper-functions.
Otherwise it would be more practical to use a namespace to collect these functions in.
Example:
class Solvers
{
public:
void solve_a(std::vector<int> data);
void solve_b(std::vector<int> data, int value);
private:
int helper_a(int a, int b);
}
But a class needs to be initialised before use.
The simplest way to make these functions usable would be to mark them static in the class:
static void solve_a(std::vector<int> data);
Then the member-functions can be used as:
Solver::solve_a(my_vector);
Another way would be to initialise the class before using:
Solver solver;
solver.solve_a(my_vector);
And the third method, not mentioned before, is by default initialising it during use:
Solver().solve_a(my_vector);