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);
Related
headerfile.h
class A
{
cv::Mat depthimagemouse;
std::string m_winname;
public:
A(const std::string &winname, const cv::Mat depth_clean);
static void onMouse( int evt, int x, int y, int flags, void* param );
};
cppfile.cpp
A::A(const std::string &winname, const cv::Mat depth_clean)
: m_winname(winname), depthimagemouse(depth_clean)
{
//something..
}
void A::onMouse( int event, int x, int y, int flags, void* param )
{
//Here I want to use depthimagemouse member variable (and other members..)
}
My question is how can I use depthimagemouse variable in onMouse method?
I'd be surprised if the library didn't explain this somewhere in its documentation, but anyway. This is standard procedure when you're using callbacks that don't support member functions, but you still need a way to access member data. So, you do the following:
Pass a reference to the instance as your user data pointer param (or a member thereof) when registering the callback.
Cast this back to the concrete type to access its members. A class static function has full access to all members of its class, via a provided instance.
So, you can do it this way:
auto &that = *static_cast<A *>(param); // <= C++03: use A &that
// Cast to const A if you want, or use a pointer, or etc.
std::cout << that.depthimagemouse << std::endl;
Or it's often nicer syntactically to immediately despatch to a member function and let it do everything:
static_cast<A *>(param)->doRestOfStuff(evt, x, y, flags);
// Include a const in the cast if the method is const
Or anywhere in between.
depthimagemouse is an instance member, means that each A instance (object if you prefer) has its own depthimagemouse. Your onMouse method is a static one, means that it is not related to any particular given instance but to all instances, and thus it's nonsense to think about accessing depthimagemouse without specifying which instance you are interested in.
Without any more information about onMouse and your model it is hard to tell you what to do. May be param can be used to specify an instance of A that the static method will receive? In that case, a cast can be used to get the instance back inside the method: A *anInstance = static_cast<A *>(param); with which you can then play: anInstance->depthimagemouse (see that we are talking about the depthimagemouse of a given instance?), etc.
I'm making a game where I have a Level class that deals with storing all the objects in vectors and changing them.
And I have another class that is called Engine.h that has static functions that calculate things based on the vectors Level owns but doesn't change anything in them. Level calls the Engine functions and does operations based on what's returned.
But since Engine needs to see the vectors that Level owns, I'm being forced to pass a bunch of pointers (const) of vectors to each Engine function so that it can do calculations based on the current state of the vectors.
Is there any way to make Engine just have access to all of Level's member variables but not be able to edit any of them. Some sort of a 'const friend"?
I just realized that there is an object level. So I also would need to have a way to assign Engine a specific object of Level with which it could be a 'const friend'.
Maybe this got to complicated. If there is no solution is it bad practice to pass a lot of member variables to the Engine functions, or is that how this is done. What about passing a pointer to Level that is const (will that make all of Levels member variables const also?)
Lets say you have some class Foo that has a member variable x you want to access. You can make const functions that access the member variables by value. Since they are const, they may not modify any of the member variables.
class Foo
{
public:
Foo() : x{0} {} // constructor
int getX() const { return x; } // this is a "getter"
void setX(int value) { x = value; } // this is a "setter"
private:
int x;
};
Then you can have your other class Bar. Maybe in some function it needs to access to x variable of Foo, you can use the getter.
class Bar
{
void doStuff (Foo a)
{
int answer = a.getX();
std::cout << answer << std::endl;
}
};
Now we can look at a quick demo. We make an instance of Foo and an instance of Bar. Then we can set the x value for the Foo, and access it from Bar's doStuff function.
int main()
{
Bar myBar;
Foo myFoo;
myFoo.setX(5);
myBar.doStuff(myFoo); // will output 5
return 0;
}
You can do stuff like this if it helps:
class Level
{
private:
std::vector<float> stuff;
public:
// give outsiders const access
const std::vector<float>& const_stuff = stuff; // c++11 else use ctor
const std::vector<float>& get_stuff() const { return stuff; } // more idiomatic
};
Is it possible to access a static member function through std::for_each?
I've hit a problem with a class I'm trying to code. I have a class Foo which in the member section initialises an object of Boo and I need to access this inside of a static member function that is used in std::foreach() details below:
Foo.h
class Foo {
public:
Foo() {
w = getInstanceOfAnotherClass(0, 0); // this works fine!
}
void Transform();
static inline void processBlock(std::vector<double> &vect);
private:
std::vector<std::vector<double> > data;
Boo* w;
};
Here is the problem: Inside of the member function Transform I have the following:
void Foo::Transform()
{
std::for_each(data.begin(), data.end(), processBlock);
}
And in ProcessBlock I have the following:
void Foo::processBlock(std::vector<double> &vect)
{
std::vector<double> vars = w.getDataBack<double>();
}
The error that is returned is that w invalid use of member 'w' in static member function, now, I know what the problem is.. But I don't know know of a workaround. I decided to create another function that wasn't static and then call this function from inside of processBlock, however, the member function cannot be called without declaring an object, which, would therefore re-set the value of w and this is not what I want.
I hope someone can help and this post isn't confusing.
FooThe way I'd do it is with a function call instead of a static function. Use
void processBlock(std::vector<double> &vect);
And
std::for_each(data.begin(),data.end(),std::bind(&Foo::processBlock,this,_1))
I am learning C++ by making a small robot simulation and I'm having trouble with static member functions inside classes.
I have my Environment class defined like this:
class Environment {
private:
int numOfRobots;
int numOfObstacles;
static void display(); // Displays all initialized objects on the screen
public:
Robot *robots;
Obstacle *obstacles;
// constructor
Environment();
static void processKeySpecialUp(int, int, int); // Processes the keyboard events
};
Then in the constructor I initialize the robots and obstacles like this:
numOfRobots = 1; // How many robots to draw
numOfObstacles = 1;
robots = new Robot[numOfRobots];
obstacles = new Obstacle[numOfObstacles];
Here is example of static function that uses those variables:
void Environment::display(void) {
// Draw all robots
for (int i=0; i<numOfRobots; i++) {
robots[i].draw();
}
}
When I try to compile, I get error messages like
error: invalid use of member ‘Environment::robots’ in static member function
I tried making numOfRobots, numOfObstacles, robots and obstacles static, but then I got errors like
error: undefined reference to 'Environment::numOfRobots'
I would greatly appreciate of someone could explain me what I am doing wrong.
Thank you!
Static methods can't use non-static variables from its class.
That's because a static method can be called like Environment::display() without a class instance, which makes any non-static variable used inside of it, irregular, that is, they don't have a parent object.
You should consider why you are trying to use a static member for this purpose. Basically, one example of how a static method can be used is as such:
class Environment
{
private:
static int maxRobots;
public:
static void setMaxRobots(int max)
{
maxRobots = max;
}
void printMaxRobots();
};
void Environment::printMaxRobots()
{
std::cout << maxRobots;
}
And you would have to initialize on the global scope the variables, like:
int Environment::maxRobots = 0;
Then, inside main for example, you could use:
Environment::setMaxRobots(5);
Environment *env = new Environment;
env->printMaxRobots();
delete env;
There are 2 issues here - the algorithm you're trying to implement and the mechanics of why it won't compile.
Why it doesn't compile.
You're mixing static and instance variables/methods - which is fine. But you can't refer to an instance variable from within a static method. That's the "invalid use" error. If you think about it, it makes sense. There is only one "static void display()" method. So if it tries to refer to the non-static (instance) variable "robots", which one is it referring to? There could be 10 ... or none.
The logic you are trying to implement.
It looks like you want a single Environment class that manages N robots. That's perfectly logical. One common approach is to make Environment a 'singleton' - an instance variable that only allows for a single instance. Then it could allocate as many robots as it want and refer to them freely because there are no static variables/methods.
Another approach is to just go ahead and make the entire Environment class static. Then keep a (static) list of robots. But I think most people these days would say option #1 is the way to go.
static members are those that using them require no instantiation, so they don't have this, since this require instantiation:
class foo {
public
void test() {
n = 10; // this is actually this->n = 10
}
static void static_test() {
n = 10; // error, since we don't have a this in static function
}
private:
int n;
};
As you see you can't call an instance function or use an instance member inside an static function. So a function should be static if its operation do not depend on instance and if you require an action in your function that require this, you must think why I call this function static while it require this.
A member variable is static if it should shared between all instances of a class and it does not belong to any specific class instance, for example I may want to have a counter of created instances of my class:
// with_counter.h
class with_counter {
private:
static int counter; // This is just declaration of my variable
public:
with_counter() {++counter;}
~with_counter() {--counter;}
static int alive_instances() {
// this action require no instance, so it can be static
return counter;
}
};
// with_counter.cpp
int with_counter::counter = 0; // instantiate static member and initialize it here
The first error says that you cannot use non-static members in static member functions.
The second one says that you need to define static members in addition to declaring them You must define static member variables outside of a class, in a source file (not in the header) like this:
int Environment::numOfRobots = 0;
You don't need any static members. To have an absolutely correct and portable GLUT interface, have a file-level object of type Environment and a file-level (non-member) function declared with C linkage. For convenience, have also a member function named display.
class Environment
{
public:
void display() { ... }
...
};
static Environment env;
extern "C" void display () { env.display(); }
A static member function is one that can be called without an actual object of that kind. However, your function Environment::display uses the variables numOfRobots and robots, which both live in a particular instance of the Environment class. Either make display non-static (why do you want it to be static?) or make the robots static members of Environment too.
In your case, I don't see a reason for making display or processKeySpecialUp static, so just make them normal member functions. If you wonder when a member function should be static, consider if that function would make sense if no objects of that class have been created (i.e. no constructors been called). If the function doesn't make sense in this context, then it shouldn't be static.
A static method cannot access instance variables. If you want to access instance variable remove static from the method. If those values can be the same through all robot instances then make them static variables and the method can remain static.
if you want to access member variables in static member function just create a static pointer of the member variable and use it in the function !!!!!
I don't get all these keywords. Specially this one static. An example of how important it is and how it used would be wonderful.
Making a member function static allows you to call the function without creating the class object.
class MyClass
{
int i;
static MyClass *ptr;
static MyClass* getInstance()
{
if(NULL == ptr)
{
ptr = new MyClass();
}
return ptr;
}
};
MyClass* MyClass::ptr = NULL;
int main()
{
MyClass *ptr = MyClass::getInstance();
}
Check out the Singleton pattern for more information on how it can be helpful.
static member functions are just like regular functions.
class Sample
{
public:
static void DoWork()
{
cout << "Static Member Function"<< endl;
}
};
//access
Sample::DoWork();
Output:
Static Member Function
You can treat them just like regular functions, that means, you can pass them to other functions which accept only regular function as argument, like this:
typedef void (*Worker)();
void Fun(Worker worker)
{
//call here just like regular function
worker(); //note: class name is not needed even if you pass static member function!
}
//pass static member function!!
Fun(Sample::DoWork);
Output:
Static Member Function
There are multiple uses for the static keyword, it does different things based on where you use it.
http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
When you declare a variable or
function at file scope (global and/or
namespace scope), the static keyword
specifies that the variable or
function has internal linkage. When
you declare a variable, the variable
has static duration and the compiler
initializes it to 0 unless you specify
another value.
When you declare a variable in a
function, the static keyword specifies
that the variable retains its state
between calls to that function.
When you declare a data member in a
class declaration, the static keyword
specifies that one copy of the member
is shared by all instances of the
class. A static data member must be
defined at file scope. An integral
data member that you declare as const
static can have an initializer.
When you declare a member function in
a class declaration, the static
keyword specifies that the function is
shared by all instances of the class.
A static member function cannot access
an instance member because the
function does not have an implicit
this pointer. To access an instance
member, declare the function with a
parameter that is an instance pointer
or reference.
Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. The advantage is that you don't need to instantiate the class to use methods or properties.
An example of when to use a static class might be for utility functions such as converters (e.g. Fahrenheit to Celcius). This type function doesn't change irregardless of any object or data.
In C# you can call a static method like this:
double F, C = 0
// TempConverter converter = new TempConverter(); <-- NOT NEEDED FOR STATIC
F = TempConverter.CelsiusToFahrenheit("100.0");
C = TempConverter.FahrenheitToCelcius("212.0");
Here is how the static class and methods are defined:
public static class TemperatureConverter {
public static double CelsiusToFahrenheit(string temperatureCelsius) {
.. conversion code..
}
public static double FahrenheitToCelsius(string temperatureFahrenheit) {
.. conversion code..
}
}
There are two types of static functions: class/struct member, and non-member. I guess you're wondering about the former (as it's more confusing)...
static member functions
If we contrast four functions:
class X
{
....
int non_static_member_f(X& a) { ... }
static int static_member_f(X& a) { ... }
friend int non_member_friend_f(X& a) { ... }
};
int non_member_f(X& a) { ... }
And given:
X x, arg;
We can write:
x.non_static_member_f(arg) - x is an existing X object instance - made accessible via the this pointer. The function has full access to all private/protected/public static/non-static members of X for operations on x and arg.
X::static_member_f(arg) can be invoked with a single X argument - if the function didn't specify an X argument, then it could be called with no existing X objects. It has full access to all private/protected/public static of X, and can access any non-static members on arg.
non_member_friend_f(arg) has the same access as X::static_member_f(arg), but is not scoped inside X (i.e. you don't need to call it with the X:: prefix, Koenig lookup resolves differently).
non_member_f(arg) can only access the public members of arg, and has no special privileges.
For completeness: static non-member functions differ from non-static in having internal linkage, which means they're not callable from other translation units but won't clash with any same-named function in those translation units.
Static functions are very useful when implementing so-called Named Constructors.
Imagine a Point class which can be either constructed from rectangular coordinates (X/Y) or polar coordinates (radius and angle):
class Point {
public:
Point(float x, float y); // Rectangular coordinates
Point(float r, float a); // Polar coordinates (radius and angle)
// ERROR: Overload is Ambiguous: Point::Point(float,float)
};
int main()
{
Point p = Point(5.7, 1.2); // Ambiguous: Which coordinate system?
...
}
This can be solved very nicely using static functions which create Point objects; such functions are called named constructors since they act like a constructor (they produce a new object) but they can have a descriptive name:
class Point {
public:
// These static methods are the so-called "named constructors"
static Point rectangular(float x, float y) { return Point(x, y); }
static Point polar(float radius, float angle) { return Point(radius*std::cos(angle), radius*std::sin(angle)); }
// ...
private:
Point(float x, float y) : x_(x), y_(y) { }
float x_, y_;
};
Clients of the class can now use these named constructors to create readable, unambiguous code:
int main()
{
Point p1 = Point::rectangular(5.7, 1.2); // Obviously rectangular
Point p2 = Point::polar(5.7, 1.2); // Obviously polar
}
Furthremore, named constructors can be used to make sure that objects of a class are always allocated with new (so that you know that you can always call delete on them). See FAQ [16.21] for more information.
static class member functions are useful:
For implementing the Factory Method Pattern
For implementing the Singleton Pattern
For loose decoupling of functions that may polute the behaviour of the class. ( Functions not necessarily members can be declared static... but even better they could be totally classic functions!) cf S.R.P.
Can be used as a function to be passed as a plain C function pointer so as to inter-operate with C code...
static functions are useful:
1. to avoid duplicate code redefinition while compiling. A static function will be redefined for each cpp unit it is included in.
And I think there are tons of other useful cases I don't remember of right now :-)
The answer from martona is a good overview of static. Relating to static members, I think Tony covers it pretty well.
The mental model I use when it comes to member functions is to consider how they might be modeled in 'C':
class A
{
public:
void mbr_1 ();
void mbr_2 () const;
void mbr_3 () volatile;
void mbr_4 () const volatile;
static void mbr_5 ();
};
Might be implemented as:
struct A { };
void mbr_1 (A * const this);
void mbr_2 (A const * const this);
void mbr_3 (A volatile * const this);
void mbr_4 (A const volatile * const this);
void mbr_5 ();
All the funcitons are members and so have appropriate 'access' to private members. The non static members have a 'this' pointer, and it is that which provides the access to a specific instances members. The static member doesn't have such a pointer and this is why we cannot access any non static members.