I'm trying to calculate the area of the circle and the rectangle by using the existing data (radius ,width, and height). But i have some errors, i hope you can help me fix it.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Shape
{
public:
virtual void Draw () = 0;
virtual void MoveTo (int newx, int newy) = 0;
virtual int GetArea()const = 0;
};
class Rectangle : public Shape
{
public:
Rectangle (int x, int y, int w, int h);
virtual void Draw ();
virtual void MoveTo (int newx, int newy);
int GetArea() {return height * width;}
private:
int x, y;
int width;
int height;
};
void Rectangle::Draw ()
{
cout << "Drawing a Rectangle at (" << x << "," << y
<< "), width " << width << ", height " << height << "\n";
};
void Rectangle::MoveTo (int newx, int newy)
{
x = newx;
y = newy;
}
Rectangle::Rectangle (int initx, int inity, int initw, int inith)
{
x = initx;
y = inity;
width = initw;
height = inith;
}
class Circle : public Shape
{
public:
Circle (int initx, int inity, int initr);
virtual void Draw ();
virtual void MoveTo (int newx, int newy);
int GetArea() {return 3.14 * radius * radius;}
private:
int x, y;
int radius;
};
void Circle::Draw ()
{
cout << "Drawing a Circle at (" << x << "," << y
<< "), radius " << radius <<"\n";
}
void Circle::MoveTo (int newx, int newy)
{
x = newx;
y = newy;
}
Circle::Circle (int initx, int inity, int initr)
{
x = initx;
y = inity;
radius = initr;
}
int main ()
{
Shape * shapes[2];
shapes[0] = new Rectangle (10, 20, 5, 6);
shapes[1] = new Circle (15, 25, 8);
for (int i=0; i<2; ++i) {
shapes[i]->Draw();
shapes[i]->GetArea();
}
return 0;
}
Rectangle::GetArea method should be const. You declared it non-const, so it is not considered an override of Shape::GetArea, so Rectangle is considered abstract.
You may want to rethink your return type too.
int Circle::GetArea() {return 3.14 * radius * radius;}
As pointed by #Cătălin Pitiș, the GetArea() methods in derived classes need to be const. Otherwise compiler will complain that you have not provided the implementation for pure virtual functions (hence the derived classes become abstract) and will not allow you to create objects of the. Additionally, you need to declare a virtual destructor for Shape class. Otherwise, you will not be able release the memory properly. Also, you are not releasing the memory in main() function. You should use delete to release the memory allocated for the objects.
Related
So I just created a struct that makes a rectangle. the struct itself look likes this
struct _rect
{
//bottom left vertex
int x = 0;
int y = 0;
// width and height
int width = 0;
int height = 0;
//top right vertex
int y2 = y + height;
int x2 = x + width;
};
//init rect
_rect rect01;
rect01.x = rect01.y = 50;
rect01.width = rect01.height = 200;
in the main cpp when I want to create an instance of it I just want to enter bottom left x and y, plus width and height and I want it to calculate top right vertex by itself, is there a way to assign x2 and y2 their values without manuly doing so ?
You should create a specific class:
class Rect
{
public:
Rect(int x, int y, unsigned int width, unsigned int height)
: m_x(x), m_y(y), m_width(width), m_height(height)
{}
int x() { return m_x; }
int y() { return m_y; }
int top() { return m_y + m_height; }
int right() { return m_x + m_width; }
private:
int m_x;
int m_y;
unsigned int m_width;
unsigned int m_height;
};
That give you the possibility to do the computation you need in the class methods.
You can also create setters and more getters if you want.
Below is the complete working example:
#include <iostream>
class Rect
{
public:
//parameterized constructor
Rect(int px, int py, unsigned int pwidth, unsigned int pheight): x(px), y(py), width(pwidth), height(pheight), x2(x + width), y2(y + height)
{
};
//getter so that we can get the value of x2
int getX2()
{
return x2;
}
//getter so that we can get the value of y2
int getY2()
{
return y2;
}
private:
int x = 0;
int y = 0;
unsigned int width = 0;
unsigned int height = 0;
int x2 = 0, y2 = 0;
};
int main()
{
//create Rect instance
Rect r(50, 50, 200, 200);
//lets check if x2 and y2 were calculate correctly
std::cout<<"x2 is: "<< r.getX2()<<std::endl;
std::cout<<"y2 is: "<< r.getY2()<<std::endl;
}
The output of the above program can be seen here.
I'm trying to build a gamengine, and I need to sort characters and rooftiles based on the y-coordinate of their feet before drawing them, so that folk/tiles infront are drawn ontop of folk/tiles behind them. I've gotten it to work with just characters, but I need rooftiles as well.
the classes are both children of renderable, and share some data. The classes are forward-declared, and there are global lists g_entities, g_tiles, and g_renderable.
class renderable {
public:
float x;
float y;
float width;
float height;
SDL_Surface* image;
SDL_Texture* texture;
void render(SDL_Renderer * renderer, camera fcamera) {
rect obj(floor((x -fcamera.x)* fcamera.zoom), floor((y-fcamera.y)* fcamera.zoom), floor(width *fcamera.zoom), floor(height * fcamera.zoom));
rect cam(0, 0, fcamera.width, fcamera.height);
if(RectOverlap(obj, cam)) {
SDL_Rect dstrect = { (x -fcamera.x)* fcamera.zoom, (y-fcamera.y)* fcamera.zoom, width *fcamera.zoom, height * fcamera.zoom};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
}
}
};
class entity: public renderable {
public:
float x;
float y;
float xagil;
float yagil;
//... other stuff, including image and texture
void render(SDL_Renderer * renderer, camera fcamera);
};
class tile: public renderable {
public:
int x;
int y;
int z = 0; //represents layer. 0 default
float width;
float height;
//... other stuff, including image and texture
void render(SDL_Renderer * renderer, camera fcamera);
};
The list is created when the map is loaded with
for (int i = 0; i < g_entities.size(); i++) {
g_renderable.push_back(g_entities[i]);
}
for (int i = 0; i < g_tiles.size(); i++) {
if(g_tiles[i]->z ==2) {
g_renderable.push_back(g_tiles[i]);
g_tiles.erase(g_tiles.begin() + i);
i--;
}
}
And then in main I planned to sort the g_renderable array instead of the g_entities array and have everything snug, but instead I get a SIGFAULT. I tracked down the problem with GDB and it turns out that g_renderable[] isnt getting informed with the attributes of g_entities[] (and probly not g_tiles[] either).
This is what I mean:
g_renderable.clear();
g_renderable.reserve(g_entities.size() + g_tiles.size()); // preallocate memory
cout << "g_entities.size" <<g_entities.size() << endl;
cout << "g_entities.size" <<g_entities.size() << endl;
cout << "g_entities height " << g_entities[0]->height << endl; //couts 122
for (int i = 0; i < g_entities.size(); i++) {
g_renderable.push_back(g_entities[i]);
}
cout << "g_renderable height " << g_renderable[0]->height << endl; //couts 0
for (int i = 0; i < g_tiles.size(); i++) {
if(g_tiles[i]->z ==2) {
g_renderable.push_back(g_tiles[i]);
g_tiles.erase(g_tiles.begin() + i);
i--;
}
}
Why doesnt my vector return the member data as expected?
Help me figure out how the line p1(10,15); works and From where p1 derive from as it was never declared.
I am learning how constructor works
i used this link link
#include<iostream>
using namespace std;
class Point
{
private:
int x, y;
public:
// Parameterized Constructor
Point(int x1, int y1)
{
x = x1;
y = y1;
}
int getX()
{
return x;
}
int getY()
{
return y;
}
};
int main()
{
// Constructor called
Point p1(10, 15);
// Access values assigned by constructor
cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
return 0;
}
When you make an instance of class Point, it automatically call constructor and do the assignment.
Point p1(10, 15);
it's like this:
Point(10, 15)
{
x = 10;
y = 15;
}
and you using 2 functions to get x,y :
cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
#include <iostream>
#include <string>
using namespace std;
struct Point {
private:
int xCord,yCord;
public:
void setX(int x);
void setY(int y);
int getX();
int getY();
int rotate(int x, int y, Point p1);
int moveHorizontally(int x, int a, int b);
int moveVertically(int y, int a, int b);
};
int main() {
Point p1;
p1.setX(1); //sets X
p1.setY(2); //sets Y
cout << p1.getX() << ", " << p1.getY() << endl; //prints current value of X & Y
p1.rotate(p1.getX(), p1.getY(), p1);
cout << p1.getX() << ", " << p1.getY() << endl;
return 0;
}
void Point::setX(int newX) {
xCord = newX;
}
void Point::setY(int newY) {
yCord = newY;
}
int Point::getY() { //This will just return the y Cord.
return yCord;
}
int Point::getX() { //This will just return the x Cord.
return xCord;
}
int Point::moveHorizontally(int x, int tempX, int tempY) {
//Move the point to the right if positive.
//Move the point to the left if negative.
int newX = tempX + (x);
return newX;
}
int Point::moveVertically(int y, int tempX, int tempY) {
//Move the point up if positive.
//Move the point down if negative.
int newY = tempY + (y);
return newY;
}
int Point::rotate(int tempX, int tempY, Point p1){
//(1,2) -->> (-2,1)
int tempX_DNC = tempX;
int tempY_DNC = tempY;
int quadrant;
if((tempX > 0) && (tempY > 0)) { //Quadrant 1: x(positive), y(positive) Then rotates to Quad 2
quadrant = 1;
tempX = -(tempY);
tempY = tempX_DNC;
} else if ((tempX < 0) && (tempY > 0)) { //Quadrant 2: x(negative), y(positive) Then rotates to Quad 3
quadrant = 2;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else if ((tempX < 0) && (tempY < 0)) { //Quadrant 3: x(negative), y(negative) Then rotates to Quad 4
quadrant = 3;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else if ((tempX > 0) && (tempY < 0)) { //Quadrant 4: x(positive), y(negative) Then rotates to Quad 1
quadrant = 4;
tempX = -(tempY_DNC);
tempY = tempX_DNC;
} else {
quadrant = 0;
}
//This will rotate the points 90* to the left.
//(1,2) will then become (-2,1)
//I could have if in quadrant1, all are positive, if in quadrant 2 the x would be negative and y would be positive
//If in quadrant 3 the x and y will both be negative, if in quadrant 4 the x would be positive and the y would be negative
cout << tempX << ", " << tempY << endl;
p1.setX(tempX);
p1.setY(tempY);
cout <<"x is: " <<p1.getX() <<endl;
cout <<"Y is: " <<p1.getY() <<endl;
}
Code is above.
So I am creating a class Point. Point has 2 private variables xCord, yCord. I want to call the rotate function and have that be able to modify the xCord, yCord but it does not. I am not sure why. I tried passing the Point p1 to the function and to see if that would fix the issue but it did not, I also tried without passing the Point p1 and just having Point p1 inside the function definition.
p1.setX(VARIABLE);
works when it is in main(). but not when I call p1.setX(VARIABLE) inside another member function.
You are passing a copy of p1 to the rotate function. Only this copy is modified.
You pass the point by value:
int rotate(int x, int y, Point p1);
^^--------pass-by-value
ie. the p1 inside the function is a copy of p1 in main that gets deleted once the function returns. If you want to change the point that is passed as parameter inside the function then pass it by reference:
int rotate(int x, int y, Point& p1);
^^--------pass-by-reference
PS: ... However, as rotate is a member function of Point you should probably rather rotate the instance on which you are calling it, change its signature to
int rotate(int x, int y);
and instead of changing the coordinates of some point passed as parameter do this:
this->setX(tempX); // this-> not really necessary, just added for clarity
this->setY(tempY);
Alternatively you keep it as is and pass the point that is supposed to be rotated as parameter, but then you should consider making the method static.
PPS: If you want to change it to pass-by-reference, you have to change the signature in the class declaration to:
int rotate(int x, int y, Point& p1);
and the definition you have to change to:
int Point::rotate(int tempX, int tempY, Point& p1) { /*...*/ }
void point::rotate() {
xcord = ycord;
ycord = xcord;
}
is all you need for basic rotation
#include <iostream>
#include "Shapes.h"
int main()
{
//variables
int height = 0;
int width = 0;
Rectangle rect = Rectangle();
Triangle tran = Triangle();
Square sqar = Square();
std::cout << "What is the width of the shape? ";
std::cin >> width;
std::cout << "What is the height of the shape?";
std::cin >> height;
rect.set_lengths(width, height);
std::cout << "If the shape is a triangle, the area is " << tran.area() << "." << std::endl;
std::cout << "If the shape is a rectangle, the area is " << rect.area() << "." << std::endl;
std::cout << "If the shape is a square, the area is " << sqar.areaByWidth() << " by the width value," << std::endl;
std::cout << "and " << sqar.areaByHeight() << " by the height value." << std::endl;
system("pause");
}
Header file:
//Our base class
class Shape
{
protected:
int width, height, shapes = 0;
public:
void set_lengths(int width, int height)
{
width = width; height = height;
}
};
//Rectangle is a shape
class Rectangle : public Shape
{
public:
Rectangle()
{
std::cout << "Created a rectangle!\n";
shapes = shapes + 1;
}
~Rectangle()
{
shapes = shapes - 1;
}
int area()
{
return width * height;
}
};
//Triangle is a shape
class Triangle : public Shape
{
public:
Triangle()
{
shapes = shapes + 1;
std::cout << "Created a triangle!\n";
}
~Triangle()
{
shapes = shapes - 1;
}
int area()
{
return width * height / 2;
}
};
//Square is a shape
class Square : public Shape
{
public:
Square()
{
shapes = shapes + 1;
std::cout << "Created a square!";
}
~Square()
{
shapes = shapes - 1;
}
int areaByWidth()
{
return width * width;
}
int areaByHeight()
{
return height * height;
}
};
When I set the values, it works fine (shows the correct value in visual studio debugger), but when I call area() it brings back -846388729 or something similiar? Why is the value being reset? I have been banging my head against a wall for hours on this. Seems like a common problem to noobies like myself but I'm not understanding the other solutions on here :(
The function set_lengths did not set the member variable correctly, just set the value back to the function arguments.
change
void set_lengths(int width, int height)
{
width = width; height = height;
}
to
void set_lengths(int width, int height)
{
this->width = width; this->height = height;
}
Or change the name of the member variables for a good habit:
int width_, height_, shapes_;
void set_lengths(int width, int height)
{
width_ = width;
height_ = height;
}
Becuase width and height are not initilized.
Change the line to:
int i = 0, j = 0, k = 0;
Also, you're only setting the dimension of the rect object, not the triangle or the square.