I got the following class:
class Foo {
private:
static float scale;
public:
static float setScale(float scale);
};
When I am trying to implement setScale like this:
float Foo::setScale(float scale) {
this->scale = scale;
return scale;
}
It throws an error:
Invalid use of 'this' outside of a non-static member function.
I really don't get this since my function is marked static.
I saw some related questions but it didn't answer my question.
So how can I fix this?
I know I can change the names and don't use this but there probably is a solution for this?
EDIT: Also when I implement the function inside the class it still throws the same error.
A static member function is not part of the class. In other words, there is only one instance of it. Notice how you access them using the scope resolution operator(Foo::setscale(1.f);), instead of the member reference operator(Foo.setscale(1.f)), because they are not members of instances of the class.
class Foo
{
public:
void DoSomething();
};
In this example, if I create a Foo f and call f.DoSomething(), what happens is that the compiler actually transforms DoSomething() into DoSomething(Foo* this) where this is the address of f.
However, since static member functions are not part of the class, the compiler does not transform them to take in a this pointer.
P.S. So why have static member functions? For one, you can limit the scope of the function to the class it is declared in.
Thank you for reading.
this pointer is not there in static member functions of class. Change the definition as follows:-
float Foo::setScale(float s) {
Foo::scale = s;
return s;
}
Change the function definition the following way
float Foo::setScale(float scale) {
Foo::scale = scale;
}
static member functions have no implicit parameter this.
In the note of paragraph #2 of section 9.4.1 Static member functions of the C++ Standard there is explicitly written that
2 [ Note: A static member function does not have a this pointer
(9.3.2). —end note ]
Also you have to define the function as having return type void because at least you are returning nothing from the function.
void Foo::setScale(float scale) {
Foo::scale = scale;
}
Related
In my code I would like to call different functions by the same name. So I used pointers, and I did work with static functions, now I would like to do the same with non-static functions and it doesn't work at all.
class Amrorder
: {
public:
....
void (*fkt)(real&, const real);
void fktAcPulse(real &rhoRef, const real y);
void fktAcPulseSol(real &rhoRef, const real y);
...
}
void Amrorder::initData(a)
{
...
switch(method){
case 2://
Amrorder::fkt=&Amrorder::fktAcPulse;
break;
case 222://
Amrorder::fkt=&Amrorder::fktAcPulse1d;
break;
}
...
for(int i=0; i<ng; ++i){
Amrorder::fkt(rhoRef, yRef);
...
}
...
}
The code is quiet big so I hope the part above is enough to understand what I want to do.
Thanks for your time!
It doesn't work because your fkt has type:
void (*)(real&, const real);
and you're trying to assign it to, e.g., &Amrorder::fktAcPulse, which has type:
void (Amrorder::*)(real&, const real);
Notice the difference. The latter is a pointer-to-member function, not just a pointer to function. These have different semantics. A pointer to function can just be called (e.g. fkt(a, b)), but a pointer to member function needs to be called on an object (e.g. (obj.*pm)(a, b)).
For simplicity, since you probably just want "something that I can call with a real& and a const real", you may want to consider the type-erased function object: std::function:
std::function<void(real&, const real)> fkt;
This can be initialized with any callable that matches the arguments, so you can assign it to a free function:
void foo(real&, const real) { ... }
fkt = foo;
A static member function:
struct S { static void bar(real&, const real) { ... } };
fkt = &S::bar;
Or a member function, as long as its bound:
fkt = std::bind(&Amrorder::fktAcPulse, this);
fkt = [this](real& a, const real b){ return this->fktAcPulse(a, b); };
The key is that you need an instance of Amrorder to call fktAcPulse, and using std::function lets you use either std::bind or a lambda to store that instance in with the functor itself.
The type of fkt declares a function pointer to a free-standing function or a static member function. But you want to assign a non-static member function pointer to it. So fkt needs to be of the type of a non-static member function pointer of class Amrorder. That type is spelled
void (Amrorder::*fkt)(real&, const real);
// ^^^^^^^^^^
When invoking a function pointer to a non-static member function, you need to specify on which object you want the member to be called (which normally defaults to this when calling a member function directly with its name).
The syntax for this is quite strange. It requires another pair of parentheses and depends on wether you call it on a pointer or an object itself:
(object.*functionPointer)(arguments);
(pointer->*functionPointer)(arguments);
So if you just want to call the function on the this pointer, you need to write
(this->*fkt)(rhoRef, yRef);
(Note that you don't need to specify the class in your code everywhere. Amrorder:: can be removed in front of every function name inside the definition of a member function of the same class.)
When you call a non-static method of a class, the compiler needs to know which instance of the class you want to execute against. So there is a hidden parameter in the call, which is a pointer to the instance.
So you need to write something like this:
Amrorder::fkt=bind( &Amrorder::fktAcPulse, this );
In a file named maze.hpp (a header file) I have the following:
class Maze
{
public:
Maze(int size);
~Maze() {}
void step();
private:
int exitRow;
};
In another file named maze.cpp I have the following:
void step(){
this.exitRow = 3;
}
int main(){
Maze maze(4);
maze.step();
}
This gives an error: invalid use of 'this' outside of a non-static member function
step is a member function of Maze. How can I access the data members of an instance of Maze from within one of its member functions?
When you define a function outside of the class declaration, you are required to provide the class name like this:
void Maze::step(){
exitRow = 3;
}
The compiler has no other way of knowing where the method that you're defining belongs.
Note that there is no need to use this when referring to members from a member function. this is still available and technically writing something like the following is valid: this->exitRow = 3;, but unnecessary. Also, this is a pointer (hence the usage of operator -> rather than .).
The lines
void step(){
this.exitRow = 3;
}
define a global function, not a member function of Maze. Also, this.exitRow is the wrong syntax. You need:
void Maze::step(){
this->exitRow = 3;
}
Your function definition should be:
void Maze::step()
{
}
The way it is now, it just defines a free standing function that does not belong to any class.
Also, this is a pointer so you need to access members by dereferencing it using ->. And it is good to note that you do not need to use this->exitRow to refer exitRow, merely mentioning exitRow inside the member function will serve the same purpose.
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))
Stated on my title, trying to compile my file with a static method inside my code.
My computeCivIndex() is trying to get 5 inputs from user and do a calculation and return the float value back.
this.sunType is for java syntax, but for V++ what should I use to link them together if both are the same name?
I have getter and setter methods in my code and also 2 constructors which is too lengthy to be posted.
This is my error:
test.cpp:159: error: cannot declare member function ‘static float LocationData::computeCivIndex(std::string, int, int, float, float)’ to have static linkage
test.cpp: In static member function ‘static float LocationData::computeCivIndex(std::string, int, int, float, float)’:
test.cpp:161: error: ‘this’ is unavailable for static member functions
The code:
class LocationData
{
private:
string sunType;
int noOfEarthLikePlanets;
int noOfEarthLikeMoons;
float aveParticulateDensity;
float avePlasmaDensity;
public:
static float computeCivIndex(string,int,int,float,float);
};
static float LocationData::computeCivIndex(string sunType, int noOfEarthLikePlanets,int noOfEarthLikemoons, float aveParticulateDensity, float avePlasmaDensity)
{
this.sunType = sunType;
this.noOfEarthLikePlanets = noOfEarthLikePlanets;
this.noOfEarthLikeMoons = noOfEarthLikeMoons;
this.aveParticulateDensity = aveParticulateDensity;
this.avePlasmaDensity = avePlasmaDensity;
if(sunType == "Type O")
//and more for computation
}
static declaration defers from static implementation. Static implementation means that your function symbol is only available within the file where it is implemented.
Simply remove the static before the function implementation. Futhermore, static function are class function, you can't access non-static members of the class in them. Those are meant to be used without object instance, an so, there is no instance variables.
float LocationData::computeCivIndex(string sunType, int noOfEarthLikePlanets,int noOfEarthLikemoons, float aveParticulateDensity, float avePlasmaDensity)
{
}
The compiler error seems reasonably clear to me:
error: ‘this’ is unavailable for static member functions
Basically, because the member is static, it doesn't execute within the context of a particular instance of the type - so using this within the method is meaningless. You do try to use this, hence the error.
From the MSDN documentation for static:
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.
It sounds like you just don't want to declare the member as being static.
(As an aside, I don't like the description saying it's "shared by all instances of the class" - I prefer the idea that it's not specific to any particular instance of the class. There don't have to be any instances created, at all.)
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.