#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
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
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!
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*>