Subclass unable to access parent class' variable - c++

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.

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 is obj1 is referenced and calling show method if it is NULL

I am trying to create the class that can only allow one object to be created at a time, so i have created private constructor and one public wrapper getInstance() method that will create object for this class, the code goes as follows
#include <iostream>
using namespace std;
class sample
{
static int cnt;
int temp;
private: sample()
{
//temp++;
cnt++;
cout<<"Created "<<++temp<<endl;
}
public:
void show()
{
cout<<"Showing \n";
}
static sample* getInstance()
{
cout<<"count is "<<cnt<<endl;
if(cnt<1)
return (new sample());
else
return NULL;
}
};
int sample::cnt=0;
int main()
{
// cout<<"Hello World";
sample *obj = sample::getInstance();
obj->show();
sample *obj1 = sample::getInstance();
if(obj1 == NULL)
cout<<"Object is NULL\n";
obj1->show();
return 0;
}
How is obj1->show() is getting called?
OUTPUT :
count is 0
Created 1
Showing
count is 1
Object is NULL
Showing
In a vacuum, this is just because your function:
public:
void show()
{
cout<<"Showing \n";
}
don't actually try to do anything with the object - to get into the correct mindset of why this works just think of a member function as an abstraction over a free function taking the object as it's first argument:
void show(Object* this)
{
cout<<"Showing \n";
}
Now it is easy to see why this works since you don't use this - the null pointer.
If you change to something ala. this:
public:
void show()
{
cout<< this->temp << "Showing \n";
}
Your program should almost certainly crash.
What is almost certainly happening here is that the compiler is optimizing the call to show by inlining it. Further, it can also make it a "pseudo-static" function, as the there is no reference inside show to any other class member.
To 'break' the optimisation (and cause a crash) you can do one of these:
Decare the show function virtual
Reference a non-static member (e.g. temp) inside the function

std::find return a class that I can't acesses functions

I come from C/C# language and now I'm trying to learn about C++ and his standards functions.
Now, I'm creating a class called IMonsterDead. I will have a std::vector<IMonsterDead*> with N monsters.
Example:
class IMonsterDead {
public:
IMonsterDead(int Id)
{
this->_Id = Id;
}
virtual void OnDead() = 0;
int Id() const {
return _Id;
}
private:
int _Id;
};
One class which implements that class:
class MonsterTest : public IMonsterDead {
public:
MonsterTest(int generId)
: IMonsterDead(generId)
{
}
virtual void OnDead()
{
std::cout << "MonsterTesd died" << std::endl;
}
};
Ok, if I access directly everything works fine. But I'm trying to use std::find.
Full program test:
int main()
{
std::vector<IMonsterDead*> monsters;
for (int i = 0; i < 1000; i++)
{
monsters.emplace_back(new MonsterTest(1000 + i));
}
int id = 1033;
std::vector<IMonsterDead*>::iterator result = std::find(monsters.begin(), monsters.end(), [id]( IMonsterDead const* l) {
return l->Id() == id;
});
if (result == monsters.end())
std::cout << "Not found" << std::endl;
else
{
// Here I want to access OnDead function from result
}
return 0;
}
So I need to access OnDead function from result but I can't. Intellisense doesn't show anything for me. The result exists.
How can I access that function? Have another better way to do that?
You need to use std::find_if() instead of std::find(). std::find() is for finding an element with a specific value, so you have to pass it the actual value to find, not a user_defined predicate. std::find_if() is for finding an element based on a predicate.
Either way, if a match is found, dereferencing the returned iterator will give you a IMonsterDead* pointer (more accurately, it will give you a IMonsterDead*& reference-to-pointer). You need to then dereference that pointer in order to access any members, like OnDead().
You are also leaking memory. You are not delete'ing the objects you new. And when dealing with polymorphic types that get deleted via a pointer to a base class, the base class needs a virtual destructor to ensure all derived destructors get called properly.
With that said, you are clearly using C++11 or later (by the fact that you are using vector::emplace_back()), so you should use C++11 features to help you manage your code better:
You should use std::unique_ptr to wrap your monster objects so you don't need to delete them manually.
You should always use the override keyword when overriding a virtual method, to ensure you override it properly. The compiler can catch more syntax errors when using override than without it.
You should use auto whenever you declare a variable that the compiler can deduce its type for you. Especially useful when dealing with templated code.
Try something more like this:
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
class IMonsterDead {
public:
IMonsterDead(int Id)
: m_Id(Id)
{
}
virtual ~IMonsterDead() {}
virtual void OnDead() = 0;
int Id() const {
return m_Id;
}
private:
int m_Id;
};
class MonsterTest : public IMonsterDead {
public:
MonsterTest(int generId)
: IMonsterDead(generId)
{
}
void OnDead() override
{
std::cout << "MonsterTest died" << std::endl;
}
};
int main()
{
std::vector<std::unique_ptr<IMonsterDead>> monsters;
for (int i = 0; i < 1000; i++)
{
// using emplace_back() with a raw pointer risks leaking memory
// if the emplacement fails, so push a fully-constructed
// std::unique_ptr instead, to maintain ownership at all times...
monsters.push_back(std::unique_ptr<IMonsterDead>(new MonsterTest(1000 + i)));
// or:
// std::unique_ptr<IMonsterDead> monster(new MonsterTest(1000 + i));
// monsters.push_back(std::move(monster));
// or, if you are using C++14 or later:
// monsters.push_back(std::make_unique<MonsterTest>(1000 + i));
}
int id = 1033;
auto result = std::find_if(monsters.begin(), monsters.end(),
[id](decltype(monsters)::value_type &l) // or: (decltype(*monsters.begin()) l)
{
return (l->Id() == id);
}
// or, if you are using C++14 or later:
// [id](auto &l) { return (l->Id() == id); }
);
if (result == monsters.end())
std::cout << "Not found" << std::endl;
else
{
auto &monster = *result; // monster is 'std::unique_ptr<IMonsterDead>&'
monster->OnDead();
}
return 0;
}
Iterators are an interesting abstraction, in this case to be reduced to pointers.
Either you receive the pointer to the element or you get an invalid end.
You can use it as a pointer: (*result)->func();
You can also use it to create a new variable:
IMonsterDead &m = **result;
m.func();
This should give the same assembly, both possible.

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.

unable to use friend class' method

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