Search code examples
c++virtual

How can I use method of which parameter is vector?


#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

class Shape{
protected:
    int _r;
    int _w;
    int _h;

public:
    Shape(double r) : _r(r) {}
    Shape(double w, double h) : _w(w), _h(h) {}

    virtual double area(vector<Shape *>){
        cout << "shape:: area " << endl;
        return _r;
    }
};

class Circle : public Shape{

public:
    Circle(double r) : Shape(r) {}
    double area(vector<Shape *>) { return _r*_r*atan(1)*4.0; }
};

class Triangle : public Shape{

public:
    Triangle(double s) : Shape(s) {}
    double area(vector<Shape *>) { return sqrt(3) * pow(_r, 2) / 4; }
};

class Rectangular : public Shape{

public:
    Rectangular(double w, double h) :Shape(w, h) {}
    double area(vector<Shape *>) { return  _w * _h ;}
};

int main()
{

    int n;
    char info;
    int value;
    int value2;
    double sum;
    vector<Shape > collection;
    vector<int> answer;

    sum = 0;

    cin >> n;

    for(int i = 0 ; i < n; i++)
    {
        cin >> info;
        if (info == 'C')
        {
            cin >> value;
            Circle c(value);
            collection.push_back(c);
        }
        else if (info == 'R')
        {
            cin >> value;
            cin >> value2;
            Rectangular r(value, value2);
            collection.push_back(r);
        }
        else
        {
            cin >> value;
            Triangle t(value);
            collection.push_back(t);
        }
    }
    for (int i = 0; i < n ; i++)
    {
        sum += collection[i].area(&collection[i]);
    }
    cout << sum << endl;
}

As you can see , I used an abstract class Shape, and the three concrete class , Circle, Rectangular, Triangle.
And I wanna sum areas of all shapes. such as
enter image description here

First input represents how many shapes we have to calculate. C for circles, R for rectangle, and T for regular triangles.

And I want to override function "area" of which parameter is vector. But my error is enter image description here

How can I solve this no viable conversion from 'std::__1::__vector_base<Shape, std::__1::allocator >::value_type'

#include <iostream>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

class Shape{
protected:
    int _r;
    int _w;
    int _h;

public:
    Shape(double r) : _r(r) {}
    Shape(double w, double h) : _w(w), _h(h) {}
    virtual double area(vector<Shape *>) = 0;
};

class Circle : public Shape{
public:
    Circle(double r) : Shape(r) {}
    double area(vector<Shape *>) { return _r*_r*atan(1)*4.0; }
};

class Triangle : public Shape{
public:
    Triangle(double s) : Shape(s) {}
    double area(vector<Shape *>) { return sqrt(3) * pow(_r, 2) / 4; }
};

class Rectangle : public Shape{
public:
    Rectangle(double w, double h) :Shape(w, h) {}
    double area(vector<Shape *>) { return  _w * _h ;}
};

int main()
{

    int n;
    char info;
    int value;
    int value2;
    double sum;
    vector<Shape*> collection;
    vector<int> answer;

    sum = 0;

    cin >> n;

    for(int i = 0 ; i < n; i++)
    {
        cin >> info;
        if (info == 'C')
        {
            cin >> value;
            Circle c(value);
            collection.push_back(&c);
        }
        else if (info == 'R')
        {
            cin >> value;
            cin >> value2;
            Rectangle r(value, value2);
            collection.push_back(&r);
        }
        else
        {
            cin >> value;
            Triangle t(value);
            collection.push_back(&t);
        }
    }
    for (int i = 0; i < n ; i++)
    {
        sum += collection[i]->area(collection);
    }
    cout << fixed << setprecision(2) << sum << endl;
}

I changed and fix!


Solution

  • Polymorphism does not work with concrete classes!

    By declaring vector<Shape> collection;, you declare a vector of Shape, not of Circle, Triangle or Rectangular. You probably want collection to be of type vector<Shape*> to be able to utilize polymorphism.

    Another issue with your code is that you don't pass collection, which is of type vector<Shape>, but collection[i] which just is of type Shape.

    This would probably also explain your error, since your compiler most likely wants to parse Shape into vector<Shape*> since that's type of the argument of area. This is not possible, and therefore probably causes your compiler error.

    Also, if you want to pass just collection, you'd have to make sure the types are matching. vector<Shape> is not implicitly convertable into vector<Shape*>