having error while compiling with static method - c++

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.)

Related

Accessor declared inside the class, and defined outside the class doesn't work

//inside the class NutritionData, declaration
double getCaloriesPerServing() const;
//Outside the class Nutrition Data, definition
double NutritionData::getCaloriesPerServing() const {
calPerServing = calFromCarb+calFromFat+calFromProtein;
return calPerServing;
}
Error: says
the expression calPerServing must be a modifiable lvalue.
Instructor directions:
1.Add a const member function named getCaloriesPerServing that returns the total calories from carb, protein and fat. Again, don't forget to mark this function as a const member function. Define this function outside of the class.
Hard to be certain without seeing the class definition for NutritionData, but it looks like you have a member variable called calPerServing. Because you are inside a const member function, that variable is const in this context; you can't assign to it:
calPerServing = ... // it's const here!
You probably want calPerServing to be a local variable inside the getCaloriesPerServing function, that is only used for this particular calculation:
double NutritionData::getCaloriesPerServing() const {
int totalCalPerServing = calFromCarb+calFromFat+calFromProtein;
return totalCalPerServing;
}
Many people find it helpful to follow a naming convention to help distinguish member variables from local variables or function parameters. For example, at my company this code might look like:
int totalCalPerServing = d_calFromCarb+d_calFromFat+d_calFromProtein;
// ^^^ local ^^ member ^^ member ^^ member

Invalid use of this in a non static member function

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;
}

static functions constant static member functions

I want to ask a simple question
Like for example in my private member I have declared static member.
static int id;
and in the public I have used getter function for this id
static int getID() const;
The compilor is giving me an error but when I dont use const it does not give any error, because this is only getter it should be constant, please tell me the reasons.
This is a static function which cannot be const, because it doesn't act on any particular instance of class. This means such function has no this pointer (passed implicitly as hidden argument) to any particular instance. You should write
static int id;
static int getID();
It is also possible to make this function non static
int getID() const;
however such a function in general should be static, as long as it doesn't need access to specific object's representation.

Why do I have to put this function static

I am trying t understand the Named Constructor Idiom in the example I have
Point.h
class Point
{
public:
static Point rectangular(float x, float y);
private:
Point(float x, float y);
float x_, y_;
};
inline Point::Point(float x, float y) : x_(x), y_(y) {}
inline Point Point::rectangular(float x, float y) {return Point(x,y);}
main.cpp
#include <iostream>
#include "include\Point.h"
using namespace std;
int main()
{
Point p1 = Point::rectangular(2,3.1);
return 0;
}
It does not compile If Point::rectangular is not static and I don't understand why...
In this context, the static keyword in front of a function means that this function does not belong to any particular instance of the class. Normal class methods have an implicit this parameter that allow you to access the members of that specific object. However static member functions do not have the implicit this parameter. Essentially, a static functions is the same as a free function, except it has access to the protected and private members of the class it is declared in.
This means you can call static functions without an instance of that class. Instead of needing something like
Point p1;
p1.foo();
You simply do this:
Point::foo();
If you tried to call a non static function like this, the compiler will complain, because non-static functions need some value to assign to the implicit this parameter, and Point::foo() doesn't supply such a value.
Now the reason you want rectangular(int, int) to be static is because it is used for constructing a new Point object from scratch. You do not not need an existing Point object to construct the new point so it makes sense to declare the function static.

How can static functions be useful?

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.