I have a class defined in header file as below:
// picture.hpp:
class Picture {
public:
int count;
void draw();
};
Corresponding implementing source file:
// picture.cpp
import "picture.hpp";
Picture::draw() {
// some code
someFunction();
}
void someFunction() {
//some code
// can I use variable "count" declared in Picture class in this function
}
Can someFunction() access members of Class Picture?
As your title says you want to access members of class from outside.There may be many ways out there. Like: making class member vaiable & function both static then call it without creating instances of class even if it is private.see-reference
But if you don't want to make member function static and use class member variable from outside,then you may use friend function.Now what friend function can do? you can read it from wikipedia or a blog or might be from here whatever suits your expectation.Now if you use friend function,you have to specify inside your class.like this
class Picture
{
public:
int count;
void draw(Picture obj);
friend void someFunction(/*other parameters if you have*/Picture obj); //as global friend
};
you can perform operations of your member variable inside somefunction() like this:
void someFunction(/*other parameters if you have*/ Picture obj)
{
//some code
// can I use variable "count" declared in Picture class in this function
printf("%d", obj.count);
return;
}
Here comes the design level problem. According to your code,you want to call somefunction() inside of your member function draw() but now somefunction() requires an object as parameter.So it can be done if you pass object in draw() member function.like this:
void Picture::draw(/*other parameters if you have*/ Picture objA)
{
// some code
someFunction(/*other parameters if you have*/ objA);
}
At last,call main function.like this:
int main()
{
Picture pic1;
pic1.draw(pic1);
return 0;
}
Now without creating instances you can not call outside the member of class(except static) [see reference] So,Here two things i have done,i have passed all parameter as 'pass by value' and made somefunction() as friend of that class. Now you have the option to ignore the above whole process as you declared count variable as public. So,use it anywhere inside your class member function just using instance & dot operator but if you desparate to use member variable outside of the class then above process might help you.
Let me know if it helps you or not.
Related
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))
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 would like to know if a friend function can change private data in the class without using a
pointer and sending out the object.
I mean does a friend function have access like a member function?
For Example:
class myinfo {
private:
char name[20];
int id;
float income;
public:
void showInfo(void);
myinfo(void);
friend void updateInfo(myinfo);
int main ( ) {
myinfo j;
updateInfo(j); // calling the friend function
return 0;
}
void updateInfo(myinfo c) {
strcat(c.name, ":updated");
c.id++;
c.income += 1.1;
Yes, but not the way you've written it... If you want the function to modify the passed in object, accept a reference rather than by value...
It appears you've not learned about references in c++.
// Declaration of function in class
friend void updateInfo(myinfo&);
implementation
void updateInfo(myinfo& c)
{
strcat(c.name, ":updated"); // now modifying passed in instance of c.
c.id++;
c.income += 1.1;
}
Btw. on a side note, prefer to use std::string and also learn about rule of three (specially for non-trivial classes such as this).
Yes, In principle, private and protected members of a class cannot be accessed from outside the same class in which they are declared. However, this rule does not affect friends.
Friends are functions or classes declared with the friend keyword.
If we want to declare an external function as friend of a class, thus allowing this function to have access to the private and protected members of this class, we do it by declaring a prototype of this external function within the class, and preceding it with the keyword friend.
See it here - http://www.cplusplus.com/doc/tutorial/inheritance/
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);