-2

I am trying to calculate area of all shapes (rectangle, rhombus, triangle, circle) through using virtual and override methods. But when I execute the code it returns 1 for the area for all shapes even though I have tried with the rectangle to alter it to input the given area multiple times in int main() it still only outputs "My figure type is My area is 1 My figure type is Triangle My area is 1 My figure type is Circle My area is 1 My figure type is Rhombus My area is 1"

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

class Figure
{
protected:
    double x;
    double y;
    string type;
public:
    Figure(double m_x, double m_y) : x{ m_x }, y{ m_y } {};
    virtual double area(double x, double y) { return 0; };
    Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }
    virtual void Print() const final;
    Figure(const Figure& obj);
    Figure() {};    
};

class Rectangle : public Figure
{
public: 
    Rectangle(double x, double y)
    {
        this->x = x; 
        this->y = y; 
        type = " Rectangle"; 
        double area();
    }

    double area(double x, double y) override {
        return x * y;
    }

    Rectangle() {};
};

class Triangle : public Figure
{
public:
    Triangle(double x, double y)
    {
        this->x = x; 
        this->y = y; 
        type = " Triangle";
        double area();
    }

    double area(double x, double y)override {
        return x * y / 2;
    }

    Triangle() {};
};

class Circle : public Figure
{
public:
    Circle(double x, double y)
    {
        this->x = x; 
        this->y = y; 
        type = " Circle"; 
        double area();
    }

    double area(double x, double y)override {
        return pow(x, 2) * 3.14;
    }

    Circle() {};
};

class Rhombus : public Figure
{
public:
    Rhombus(double x, double y)
    {
        this->x = x; this->y = y; type = " Rhombus"; double area();
    }

    double area(double x, double y)override {
        return x * y / 2;
    }

    Rhombus() {};
};

void Figure::Print() const 
{
    cout << "    My figure type is" << type 
         << "   My area is " << &Figure::area;
}

int main()
{
    Rectangle rectangle;
    rectangle.area(5.4,6.2);
    rectangle.Print();
    Triangle triangle(4.5,5.3);
    triangle.Print();
    Circle circle(6.6, 8.8);
    circle.Print();
    Rhombus rhombus(3.4,5.4);
    rhombus.Print();
}
Chris
  • 26,361
  • 5
  • 21
  • 42
  • 1
    Side note: Whatever you expect `double area();` in `this->x = x; this->y = y; type = " Rhombus"; double area();` to do, it's almost certainly not doing it. `double area();` looks exactly like a function declaration, so the compiler is using it as a function declaration. – user4581301 Jul 12 '22 at 18:03
  • 1
    Also, an initializer list should be used. – Chris Jul 12 '22 at 18:04
  • Side note: `Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }` makes `Figure(double m_x, double m_y) : x{ m_x }, y{ m_y } {};` impossible to use because there are now two viable candidates for the `Figure` constructor that accepts two `double` parameters. The compiler can't decide which to use and will vomit out an error. – user4581301 Jul 12 '22 at 18:10
  • Side note: in `Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }` `m_x = x;` appears to be assigning backwards. The parameter `m_x` is being set to the uninitialized and unknown value of `x`. – user4581301 Jul 12 '22 at 18:18
  • `virtual void Print() const final;` declares `Print` `virtual` and `final` Since `Figure` is the start of the inheritance hierarchy, this is not particularly helpful. It effectively says, 'My children can and also cannot override my `Print` function." If derived classes cannot override the function there is no point to declaring it virtual. – user4581301 Jul 12 '22 at 18:23
  • Side note: There is no need for this copy constructor: `Figure(const Figure& obj);` as there are no resources owned by `figure` that require special handling. See the [Rule of Zero](https://en.cppreference.com/w/cpp/language/rule_of_three). I recommend removing it or defaulting it. – user4581301 Jul 12 '22 at 18:25
  • It looks like you haven't yet decided if a Rectangle is an object with its own height and width (member variables x & y, no parameters to call area function) or an engine with no state of its own that does stuff about rectangles if feed info about a specific one (no member variables storing dimensions, dimensions provided by arguments to area function). You need a consistent design with pieces that fit together & work together. – Avi Berger Jul 12 '22 at 18:29
  • I edited it with your suggestions and it is getting better but it is now returning me a 0 and I change the 0 in line 14 it will output the new number but the override function of returning different things from each function does not execute. I am new user so I do not know if adding a comment like this vs answering is also not the right way. – Larrythelobster Jul 12 '22 at 18:31
  • Once a question has been correctly answered, do not change the question in such a way that the answers are invalidated or rendered obsolete. – user4581301 Jul 12 '22 at 18:55
  • Ok, sorry. Why would the override not work even if it overrides the function call? – Larrythelobster Jul 12 '22 at 18:57
  • `Figure::area(x, y)` explicitly calls `Figure::area`. No overload resolution takes place. Call `area(x,y)` instead and the program will figure out which is the correct `area` function to call. – user4581301 Jul 12 '22 at 19:08
  • Side note: Since the class already knows `x` and `y`, why pass them in? This allows a user to do something really dumb like call `area(42,24)` on a rectangle that is 3 by 2. Remove the parameters and use the member variables instead. – user4581301 Jul 12 '22 at 19:10
  • 2
    There are a lot of mistakes in the code and holes in your understanding. I recommend that you get yourself [a good introductory C++ text](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) because whatever you are currently trying to learn from appears to suck harsh. Errr... be insufficient. – user4581301 Jul 12 '22 at 19:14
  • I struggle with writing code on my own. But I finished this and it works now! Thanks for the help! I do learn by reading things and watching tutorials but no matter how much I study, the "writing the code" part gets impossible for me at times. – Larrythelobster Jul 12 '22 at 19:39
  • 1
    One more thing to learn: Use of a debugger. Try to find a video tutorial for your compiler/IDE/OS. – Ulrich Eckhardt Jul 12 '22 at 19:51

2 Answers2

1

You are getting 1 because a valid function pointer is treated as true.

You should call the function area like Figure::area(x, y) instead of getting the address of the function area like &Figure::area.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • I recommend an improvement to this answer as the question's asker took it a bit too literally and replaced `&Figure::area;` with `Figure::area(x, y)` instead of merely `area(x,y)` and allowing polymorphism to take place. – user4581301 Jul 12 '22 at 18:58
0

it's simple. really. When you do rectangle.area(x, y); you just return the value you obtain from the variables that you passed in. You never assign a value to the x and y of the actual rectangle. So when you do print the area of the rectangle you use its real x and y, which do not have a value assigned to them, hence resulting in a 1. it's the same for the other shapes.

thegrult
  • 1
  • 2