Accessing a private data member from within a member function - c++

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.

Related

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

C++ call static function of class in main

I have a class
class Triedenie_cisla{
public:
Triedenie_cisla(int *poleHodnot, int ddlzka);
int *pole, dlzka;
double bubble_cas, selection_cas, insertion_cas, quick_cas;
vector<int> mnozina_int;
string vypis_pola();
void BubbleSort_int();
void SelectionSort_int();
void InsertSort_int();
void QuickSort_int();
void static zorad_Sorty();
};
And the function
void Triedenie_cisla::zorad_Sorty(){
if ( (quick_cas<bubble_cas) && (quick_cas<selection_cas) && (quick_cas<insertion_cas) ) {
cout << "The best one is Quick Sort with time "<< quick_cas << " ms"<< endl;
}
}
And in my main.cpp I need to call this function. Triedenie_cisla::zorad_Sorty();
I used static thkinking that may help calling me function without creating object, but I always get these errors
error C2597: illegal reference to non-static member
'Triedenie_cisla::bubble_cas'
error C3867: 'Triedenie_cisla::bubble_cas': function call missing
argument list; use '&Triedenie_cisla::bubble_cas' to create a pointer
to member
How to solve the problem ? Thanks much, I am quite new at c++
Since zorad_Sorty is static, it can only access static members. But your implementation accesses non-static members.
If you need to access non-static members of this class, you will have to instantiate an instance of it.
Alternatively, if you must use a static method, you will have to implement that method using only static members.
As the error says you cannot use non-static members in a static function.
You could gradually make everything you need to use static, but as it probably makes more sense just to create the object in main, and use it.
e.g.
(edit) If you had a default constructor...
//...
Triedenie_cisla object;
object.zorad_Sorty();
Otherwise provide the parameters it needs:
Triedenie_cisla object(&poleHodnot, ddlzka);
object.zorad_Sorty();

How to access a non-static member from a static member function in C++?

I wrote the following code:
class A
{
public:
int cnt;
static void inc(){
d.cnt=0;
}
};
int main()
{
A d;
return 0;
}
I have seen this question:
How to call a non static member function from a static member function without passing class instance
But I don't want to use pointer. Can I do it without using pointers?
Edit:
I have seen the following question:
how to access a non static member from a static method in java?
why can't I do something like that?
No, there is no way of calling a non-static member function from a static function without having a pointer to an object instance. How else would the compiler know what object to call the function on?
Like the others have pointed out, you need access to an object in order to perform an operation on it, including access its member variables.
You could technically write code like my zeroBad() function below. However, since you need access to the object anyway, you might as well make it a member function, like zeroGood():
class A
{
int count;
public:
A() : count(42) {}
// Zero someone else
static void zeroBad(A& other) {
other.count = 0;
}
// Zero myself
void zeroGood() {
count = 0;
}
};
int main()
{
A a;
A::zeroBad(a); // You don't really want to do this
a.zeroGood(); // You want this
}
Update:
You can implement the Singleton pattern in C++ as well. Unless you have a very specific reason you probably don't want to do that, though. Singleton is considered an anti-pattern by many, for example because it is difficult to test. If you find yourself wanting to do this, refactoring your program or redesigning is probably the best solution.
You cannot use non-static member variables or functions inside a static function without using pointers.
You don't need a pointer per se, but you do need access to the object through which you are accessing the non-static variable. In your example, the object d is not visible to A::inc(). If d were a global variable rather than a local variable of main, your example would work.
That said, it's curious why you'd want to go to any great effort to avoid using pointers in C++.

C++: "unresolved overload function type" between classes

This is probably something elementary, I have a function from one class (called cell) with identifier woo_func_ptr taking a pointer to function of type void with no arguments (void (*void_ptr)(void)) (which I typedef). In another class, I have an object of cell and I use the method woo_func_ptr. It won't allow me to, I get the error in the above title. If these two functions were not embedded inside a class, they would work fine
typedef void (*void_ptr)(void);
double WOO{0};
struct cell {
void woo_func_ptr(void_ptr jo)
{
jo();
}
};
class woosah
{
public:
void woo_func()
{
WOO+=rand();
std::cout << WOO << std::endl;
};
void run()
{
// other stuff
temp_cell.woo_func_ptr(woo_func);
// yet more stuff
}
cell temp_cell;
};
First of all pointer to woosah member function should be declared as
typedef void (woosah::*void_ptr)(void);
and then compiler would complain that it needs to see woosah definition while parsing this statement.
If you let compiler parse class woosah first by moving it up then it will complain that type cell is not defined (since it is contained within woosah). That wil still not solve your problem because of cyclic dependency while parsing.
One way is to solve cyclic dependency is by making temp_cell a pointer to cell instance and have it contained within woosah.
Also note, the syntax to call member function is by using .* or ->*
void run()
{
// other stuff
temp_cell->woo_func_ptr(temp_cell->*woo_func); // assuming temp_cell is pointer to some cell instance
// yet more stuff
}
http://msdn.microsoft.com/en-us/library/b0x1aatf(v=vs.80).aspx shows similar errors and their fixes.
A member function is not like a regular function. That's why there's a seperate "pointer to member function" type. It's because member functions are passed the implicit this pointer.
In fact, the standard even limits (severly) the casting of pointer to member function.
That's the source of your error.
You could use a static class function...
Change
void woo_func()
to
static void woo_func()
This will of coarse may not be what you want if you are trying to access data members of a particular object.
Member functions are kind of special and should not be treated as normal functions.

C++ static member functions and variables

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 !!!!!