unable to use friend class' method - c++

I have a problem with my code. I have two classes, Run and Robot, and I want an object of type Robot to change a private member of an object of type Run. To be specific, I want to increment the value of 'x' in the following code.
The following errors pop up:
error: 'getX' was not declared in this scope
error: 'getX' was not declared in this scope
I have pinpointed with an arrow (<---) the line where the error occurs. The following code is just a test, just to learn how to use the 'friend' keyword for a project.
#include <iostream>
#include <vector>
using namespace std;
class Robot;
class Run{
friend class Robot;
private:
int x;
vector<Robot*>robots;
public:
Run();
vector<Robot*>*getRobots();
void createRobot();
void movAll();
void setX(int);
int getX();
};
class Robot{
friend class Run;
public:
Robot();
void movingRobot();
};
Run::Run(){}
vector<Robot*>*Run::getRobots(){return &robots;}
void Run::createRobot(){getRobots()->push_back(new Robot);setX(1);}
void Run::movAll(){getRobots()->at(0)->movingRobot();}
int Run::getX(){return x;}
void Run::setX(int c){x=c;}
Robot::Robot(){}
void Robot::movingRobot(){setX(getX()+1);} <-------------------------
int main(){
Run Sim;
Sim.createRobot();
Sim.movAll();
}
Using the 'friend' keyword will definitely help on my project, so I am trying to understand how to use it.

You're just calling getX() and setX() as if they're methods of Robot. You need to call the function against an instance of Run, and in this case you don't need it to be a friend because getX() is public anyway.
That said, do you want each Robot to have an x value that you want to increment? In that case, you need it to be a member of Robot rather than Run.
If you want Run to have a single value of x that all instances of Robot can access and modify, then just make x static, then access it directly rather than calling the public methods, which don't require another class to be a friend anyway.

You called getX as if it were a function of the Robot-class. You need a run object to call it:
run.getX()

Ok you can remove the getX() function from The Robot class as it has no code body at present anyway, and for internal use the robot class can always utilise its X variable. Run doesn't need to have a friend class Robot, as Robot should not need to look into Run for anything, and as Run contains a vector of pointers to instances of Robot it can access any values of Robot instances by looking at the contents of its vector (for example myRunInstance.getRobots()[1]->getX() would return the x value of the 2nd robot in the vector of robots).
Now the getX function will have to vary a tad if it is to remain in the Run class: you will need to specify a way to make it gather the information of a specific instance of the Robot class, presumably from its vector of Robots. I have respecced your code above and added a small proof of concept set of code to the main, makes 10 robots moves them all using moveall, then sets Johnny5 to a special place (because he IS special:) Something along the lines of:
#include <iostream>
#include <vector>
using namespace std;
class Run;
class Robot{
friend class Run; // allows the Run class to access all the private data as if it were its own
private:
int x;
public:
Robot() {};
void setX(int newX) { x= newX; }
int getX() { return x; }
void movingRobot() { x+=1; }
};
class Run{
private:
vector<Robot*> robots;
public:
Run(){};
vector<Robot*> *getRobots() { return &robots; }
void createRobot() { robots.push_back(new Robot()); robots.back()->x =1; }
void movAll() { for (int i=0;i<robots.size();i++){ robots[i]->movingRobot();} }
int getX(int robotPosition){ return robots[robotPosition]->x; } //uses the friend status to read directly from Robot class instances x
void setX(int rpos, int xval){ robots[rpos]->setX(xval); }
};
int main()
{
Run *Sim = new Run();
for (int i =0; i< 10; i++)
{
Sim->createRobot();
Sim->setX(i,i); // uses the Run setX
std::cout << "Robot " << i << "(starting position): " << Sim->getRobots()->at(i)->getX() << std::endl;
}
Sim->movAll();
// lets move Johnny 5 to 55 as well...
(Sim->getRobots()->at(4))->setX(55); // uses the robot setx
for (int i=0; i< 10; i++)
{
std::cout << "Robot " << i << "(final position): " << Sim->getRobots()->at(i)->getX()<< std::endl;
}
return 0;
}
Source also viewable with sample output at Ideone

Related

Passing `this` to a function as a shared_ptr

I am writing some example code that hopefully captures my current struggle.
Let's assume I have a class for some general shapes Shape
and a nice Function that doubles the perimeter of any shape
float DoublePerimeter (shared_ptr<Shape> shape)
return 2*shape->GetPerimeter();
};
Is it possible to use such a function in a class itself?
class Square : Shape {
float side = 1;
public:
void Square(float aside) : side(aside) {;}
float GetPerimeter(){return 4*side;}
void Computation() { DoublePerimeter (??????);}
};
What can I pass in the ?????? to make this work? I tried using something like
shared_ptr<Shape> share_this(this);
and also tried enable_shared_from_this<> for my class, however the pointer that I pass to the function always returns null on lock. Is this even possible, or is this bad design? Am I forced to make this function a member function?
If you don't want to use enable_shared_from_this, perhaps because your objects are not always owned by a shared pointer, you can always work around it by using a no-op deleter:
void nodelete(void*) {}
void Square::Computation() { DoublePerimeter({this, nodelete}); }
but it's a hack (and a fairly expensive one at that, since you're allocating and deallocating a control block just to con the function you're calling).
A cleaner solution, albeit one that might require more typing, is to separate your free function implementation from the ownership scheme:
float DoublePerimeter(Shape const& shape)
return 2*shape.GetPerimeter();
};
float DoublePerimeter(std::shared_ptr<Shape> shape)
return DoublePerimeter(*shape);
};
void Square::Computation() const { DoublePerimeter(*this); }
I've tried it out. It seems to work for me. See here or below. I fixed some small issues and made Computation return a value for demonstration purpose.
#include <memory>
#include <cassert>
#include <iostream>
class Shape {
public:
virtual float GetPerimeter(){return 0;}
};
float DoublePerimeter (std::shared_ptr<Shape> shape){
return 2*shape->GetPerimeter();
}
class Square : public Shape, public std::enable_shared_from_this<Square> {
float side = 1;
public:
Square(float aside) : side(aside) {}
float GetPerimeter(){return 4*side;}
float Computation() {
return DoublePerimeter (this->shared_from_this());
}
};
int main(){
auto square = std::make_shared<Square>(3.0);
std::cout <<square->Computation() << std::endl;
return 0;
}
edit:
Example for #pptaszni's comment. Changing the main to:
int main(){
Square square{3.0};
std::cout << (&square)->Computation() << std::endl;
return 0;
}
will result in a runtime error:
Program returned: 139
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr

How do I call a function in one class from another class? (C++)

I'll start out with some context.
Making a simple game.
I have two classes, one called BouncingBall, and the other called ASCIIRenderer.
I have a list of instructions to follow, but some of the instructions aren't entirely clear.
First instruction was to create a pointer in BouncingBall called m_pRenderer, and have it point to a member variable in ASCIIRenderer. It wasn't specified which member variable I had to point to, and both existing member variables in there were private, so I made my own and called it Renderer.
Second instruction (the one I need help with) is when I'm writing a function for the BouncingBall class to call SetPixel using the m_pRenderer, and with three variables as parameters.
SetPixel is the name of a public function in the ASCIIRenderer class, and the instruction states I have to call it by using the pointer somehow.
Summary: I need to call a class' function from within the function of a separate class using a pointer.
Could someone explain to me what syntax I would use to accomplish this?
Based on the details you provided this is what I gathered. Assuming the BouncingBall class would get the X and Y pos and call the function foo with
the X and Y values to have the Renderer set. Also, I don't know how you will
initialize the pointer as it's not detailed above. Hope this helps.
class BouncingBall
{
public:
void foo( int posX, int posY)
{
m_pRenderer->setPixel( posX, posY);
}
private:
ASCIIRenderer* m_pRenderer;
};
The code I have included below shows an example of a class, in this case Ball, having a pointer to another class, in this case Renderer, injected and stored for later use.
The Ball class can then call public functions on the Renderer class using the 'arrow' syntax pointer->MemberFunction(arg1, arg2);
#include <iostream>
class Renderer
{
public:
/* Constructor and other functions omitted */
void SetPixel(const int x, const int y) const;
};
void Renderer::SetPixel(const int x, const int y) const
{
std::cout << "Set pixel: (" << x << ", " << y << ")" << std::endl;
}
class Ball
{
public:
Ball(const Renderer *const renderer, const int posX, const int posY);
void Render() const;
private:
const Renderer* _renderer;
int _posX;
int _posY;
};
Ball::Ball(const Renderer *const renderer, const int posX, const int posY)
: _renderer(renderer), _posX(posX), _posY(posY)
{}
void Ball::Render() const
{
_renderer->SetPixel(_posX, _posY);
}
int main()
{
const Renderer renderer;
const Ball ball(&renderer, 10, 20);
ball.Render();
return 0;
}
The output of the program is: Set pixel: (10, 20)

Need help understanding this piece of code from a book

This code is from "Sams Teach Yourself C++".It might be something simple but I'm having a hard time trying to figure this out. I get the same output if I don't use the getSpeed() method. So do I need this? If not, why does this book use it?
#include <iostream>
class Tricycle
{
public :
int getSpeed();
void setSpeed(int speed);
void pedal();
void brake();
private :
int speed;
};
int Tricycle::getSpeed() //<-- Why do I need this method
{
return speed;
}
void Tricycle::setSpeed(int newSpeed)
{
if (newSpeed >= 0)
{
speed = newSpeed;
}
}
void Tricycle::pedal()
{
setSpeed(speed + 1);
std::cout << "\nPedaling; tricycle speed " << speed << " mph\n";
}
void Tricycle::brake()
{
setSpeed(speed - 1);
std::cout << "\nBraking ; tricycle speed " << speed << " mph\n";
}
int main()
{
Tricycle wichita;
wichita.setSpeed(0);
wichita.pedal();
wichita.pedal();
wichita.brake();
wichita.brake();
wichita.brake();
return 0;
}
This Method return the Value from Speed.
So if you call setSpeed with value greater as 0 then the Speed Value are set to the new Value. Declared as private int variable.
As example
int main()
{
Tricycle wichita;
wichita.setSpeed(10);
int mySpeed= wichita.getSpeed();
}
The Value of mySpeed is now 10.
Since Speed is a private variable, you cannot retrive/set its value outside the class scope. So here we have used setSpeed and getSpeed public functions through which we can retrive/set Speed to tricycle object outside the class scope.
For example,
Tricycle myTricycle = new Tricycle();
// to set speed of tricycle use,
myTricycle.setSpeed(100);
// to retrive speed of tricycle object use,
myTricycle.getSpeed(); // returns 100;
Because you cannot access the private members directly from the main() function or somewhere else. But you can use a public function to access the private elements of an object of any class. In spite of this, you cannot access those private elements. In your code, speed is a private member and to get the value of this, a public function namely getSpeed is being used.

Is it possible to access a variable in a sketch from a class (Arduino)?

Say I want to get a value of a variable in a sketch from a class I wrote like
sketch
int device;
void setUp() {
device = 1;
}
And I have a class
SomeClass.cpp
void Device::checkTimedEvent() {
someDevice = device; //variable from sketch
}
I know it's possible to access members from another class where I can include the class and use the :: scope operator but not sure how the sketch relates to classes.
thanks
It appears that the usual C/C++ "extern" syntax works in Arduino as if the sketch file were a .cpp file:
Sketch:
int device = 123;
SomeClass.cpp:
extern int device;
void SomeClass::checkTimedEvent() {
someDevice = device; // variable from sketch
// will display "123" (or current value of device)
// if serial output has been set up:
Serial.println("device: " + String(device));
}
You may need to worry about startup and initialization order, depending on the complexity of your project.
class Test
{
public:
int N = 0;
};
Test t;
int someNumber = t.N;
The best way to do this is to pass the value into the function as a parameter. Here's a simple example:
Class:
class Test
{
public:
void doSomething(int v);
private:
int myValue;
};
void Test::doSomething(int v)
{
myValue = v;
}
Sketch:
Test t;
int someNumber;
void setup()
{
someNumber = 27;
t.doSomething(someNumber);
}
The setup() function here passes global variable someNumber into the class's member function. Inside the member function, it stores its own copy of the number.
It's important to note that it has a completely independent copy of the number. If the global variable changes, you'd need to pass it in again.
As much as Bloomfiled's answer is correct using the the more accepted practice of employing Getter and Setter functions. Below demonstrates this along with making the attribute public and directly accessing it.
class Test
{
public:
void SetMyValue(int v);
int GetPublicValue();
int GetPrivateValue();
int myPublicValue;
private:
int myPrivateValue;
};
void Test::SetMyValue(int v)
{
myPublicValue = v;
myPrivateValue = v;
}
int Test::GetPublicValue()
{
return myPublicValue;
}
int Test::GetPrivateValue()
{
return myPrivateValue;
}
Test t;
int someNumber;
void setup()
{
someNumber = 27;
t.SetMyValue(someNumber); // set both private and public via Setter Function
t.myPublicValue = someNumber; // set public attribute directly.
someNumber = t.GetPublicValue(); // read via Getter
someNumber = t.GetPrivateValue();
someNumber = t.myPublicValue; // read attribute directly
}
void loop() {
// put your main code here, to run repeatedly:
}

Subclass unable to access parent class' variable

I'm making a program whereby I have a Square class which is a subclass of Shape class
But my program crashes when the subclass tries to access variable from parent class.
Here is my code:
class Shape2D
{
public:
string shape;
void setShape(string newShape);
string getShape();
string specialType;
void setSpecialType(string newSpecialType);
vector <int> shapeXCoordi;
void setshapeXCoordi(int newshapeXCoordi);
vector <int> shapeYCoordi;
void setshapeYCoordi(int newshapeYCoordi);
void toString();
virtual int computeArea()
{
return 0;
}
void displayArea();
};
For testing purpose, I only make this computeArea() return the x-coordinate.
class Square : public Shape2D
{
public:
int computeArea()
{
return shapeXCoordi[0];
}
};
int main()
{
if (aShape2D[0].getShape() == "Square")
{
Shape2D *pShape2D;
pShape2D = &aSquare;
cout << "Area: " << pShape2D -> computeArea() << endl;
}
}
I did a couple of test, if I were to change return shapeXCoordi[0]; to return 123;, it works fine.
I also tried return shape; but it will not display anything, although this time, it doesn't crash.
So I'm guessing there is something wrong when SquareClass is trying to access shapeXCoordi[0] from ShapeClass
Can anyone enlighten me on this situation?
You need to initialize the shapeXCoordi in your constructor by calling setshapeXCoordi first. Since you are accessing shapeXCoordi, an uninitialized vector, there are no elements in it. Hence when you access it using [0] it returns an error.
You can add a sanity check to computeArea() to ensure there is an element in shapeXCoordi before you access it:
int computeArea()
{
assert(shapeXCoordi.size() != 0);
return shapeXCoordi[0];
}
Also, I recommend using .at(0) instead of [0], this way you get actual error handling instead of a crash.