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.
Related
Imagine I have a C++ class called MyClass.
Imagine that I have no access to the source code of MyClass ... it is contained in a library and I am supplied only the library and the header file for MyClass.
Imagine that the class itself requires environment pre-configuration ... for example ... before the constructor of the class can be called, I need to do some setup. The class is normally meant to be used as follows:
void func() {
doGlobalSetup();
MyClass myInstance(1,2,3);
myInstance.doSomething();
...
}
Now I have the situation where we need to create a global instance of the class such as:
MyClass myInstance(1,2,3);
int main(int argc, char *argv[]) {
doGlobalSetup();
myInstance.doSomething();
}
The problem is that in this story, the instance of MyClass is created before the call to doGlobalSetup(). It is instantiated before main() is called. What I want to do is either defer the creation of myInstance() till later or be able to run doGlobalSetup() somehow before the instantiation of the class.
This is a simplification of the actual story ... so let us assume:
I can't change the internals of MyClass.
There must be an instance variable called myInstance of type MyClass (I can't change the logic to MyClass *pMyInstance).
Many thanks for reading.
Since you've constrained the problem such that new cannot be used, you should be able to create the object as always and copy it to the global instance. For example:
MyClass createMyClass()
{
doGlobalSetup();
return MyClass(1, 2, 3);
}
MyClass myInstance = createMyClass();
int main()
{
myInstance.doSomething();
return 0;
}
Does it suit your needs?
namespace
{
int doStaticGlobalSetup()
{
doGlobalSetup();
return 0;
}
}
MyClass myInstance(doStaticGlobalSetup() + 1,2,3);
int main() {
myInstance.doSomething();
return 0;
}
If you absolutely have to defer any constructor calls until after global initialization is done, and want to be sure that no static order initialization fiasco happens, there is a way: make myInstance a reference to uninitialized block of memory and create object in it using placement new after global initializaton.
#include <iostream>
#include <type_traits>
struct foo
{
foo() { std::cout << "created\n"; }
void meow() { std::cout << "used\n"; }
~foo() { std::cout << "destroyed\n"; }
};
void doGlobalSetup() { std::cout << "Global setup\n"; }
//Actual implementation
namespace {
typename std::aligned_storage<sizeof(foo), alignof(foo)>::type bar;
}
foo& instance = reinterpret_cast<foo&>(bar);
//Allows automatic creation and destruction
struct initializer
{
initializer()
{
if (!initialized)
new (&instance) foo();
initialized = true;
}
~initializer()
{
if(initialized)
instance.~foo();
initialized = false;
}
private:
static bool initialized;
};
bool initializer::initialized = false;
int main()
{
doGlobalSetup();
initializer _;
instance.meow();
}
Use a static variable inside a function.
MyClass &myInstance() {
doGlobalSetup();
static MyClass myInstance(1,2,3);
return myInstance;
}
void func() {
myInstance().doSomething();
}
You probably already got the answer you wanted. But just to cover the whole spectrum: if, for some reason, you want to make sure that other places in the code don't accidentally construct MyClass independently of your global variable--and before the global setup has been made--you need to solve this with linking.
If you're on Linux, you can LD_PRELOAD a shared-object containing just the symbol for MyClass's constructor. In it, you declare the setup function accordingly, and let the dynamic linker do the job for you. Then, inside the constructor, you call the setup function, and then do a dlsym("...", RTLD_NEXT) to get the pointer to the original constructor, and you call it, passing it the arguments you got. Of course, you maintain and check a static flag for whether setup has already been performed.
Again, this is probably overkill for you, but I'm posting it just in case someone needs (and is able to use) this kind of solution.
P.S. This is what you get when you rely on global state! :)
First, bear in mind that given a library init function like doGlobalSetup there is a distinct nonzero chance the library will just not work if you create a global instance.
Otherwise it's super easy to create an initializer with the comma operator:
bool do_my_setup = (doGlobalSetup(), true);
MyClass myInstance(1,2,3);
Within the GCC compiler environment there is a function attribute capability called constructor. This allows us to flag a function definition with the ability for it to be automatically invoked before main is called and, most importantly before any class constructors are invoked.
Referring back to the original problem definition ... if the doGlobalSetup() function is modified from:
void doGlobalSetup() { ... }
to
__attribute__((constructor)) void doGlobalSetup() { ... }
then its invocation will occur before main is called and also before any static class instance constructors are called. The explicit call to this function would also be removed from main() as its work has been performed implicitly.
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;
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
I was trying to write a convenience function to provide a pointer to an unordered_map which is buried inside of an object contained by another object. For some reason the compiler (Visual Studio 2010) is forcing me to declare the pointer as a pointer to a const object.
The function code looks like this: (I didn't want it to have a const return type):
const ezx::iserver::strategy_map* strategy_map(const ezx::iserver::StrategyInfo* strategyInfo)
{
if (strategyInfo)
{
const ezx::iserver::strategy_map* map = &strategyInfo->strategyTVS.tagValues;
return map;
}
return NULL;
}
The object is defined without any const modifier:
class TagValueMsg : public EZXMsg
{
public:
strategy_map tagValues;
...
}
This TagValueMsg is contained as a member field in another class.
class StrategyInfo : public EZXMsg
{
public:
TagValueMsg strategyTVS;
...
}
Since nothing is declared const anywhere, I don't understand why const ezx::iserver::strategy_map* is required?
Because your enclosing object is also const when passed into the function:
strategy_map(const ezx::iserver::StrategyInfo* strategyInfo)
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);