So currently, I'm working on a C++ practice about OOP using polymorphism. I try to store my derived class objects in a collection through a base class pointer. My base class name is shape. My derived class are rectangular, circle and triangle. This is my main.cpp file, I include all header files I need and I compile this.
#include "rectangular.h"
#include "circle.h"
#include "triangle.h"
int choose(short &i, short &h, shape* shp[]);
int get_shape(short &h, shape* shp[]);
int main()
{
rectangular rec;
circle c;
triangle tr;
shape* shp[] {&rec, &c, &tr};
bool flag = true;
short i {0};
short h {0};
return 0;
}
int get_shape(short &h, shape* shp[])
{
std::cout << "Enter a number to choose shape:\n";
std::cout << "1. Rectangular\n";
std::cout << "2. Circle\n";
std::cout << "3. Triangle\n";
std::cin >> h;
short a{0};
for(shape* shp_ptr : shp) //error appears here
{
if(a == h)
{
std::cin >> *shp_ptr;
} else if(a > h)
{
break;
}
a++;
}
}
VS code throw a error message: "this range-based 'for' statement requires a suitable "begin" function and none was found"
I tried to google this error and I saw a bunch of solution, but none of them are the same as my problem. Some of them say I need to have an iterator as begin
and end
, but I don't really know how to do it.
I am a C++ newbie and English is not my mother tongue so I'm sorry if my words make you confuse. I really hope that I'll get help in here.
My base class and derived class code if you need them to test on VS code:
shape.h
#ifndef SHAPE_H
#define SHAPE_H
#include <iostream>
class shape
{
friend std::ostream& operator<< (std::ostream& out, const shape& p); //declaration. Non-member function
friend std::istream& operator>> (std::istream& in, shape& p);
public:
shape() = default;
//virtual void Input() const = 0;
virtual double area() const = 0;
virtual double perimeter() const = 0;
virtual void ostream_shape(std::ostream& out) const = 0;
virtual void istream_shape(std::istream& in) = 0;
~shape() = default;
};
#endif
shape.cpp
#include "shape.h"
std::ostream& operator<< (std::ostream& out, const shape& p)
{
p.ostream_shape(out);
return out;
}
std::istream& operator>> (std::istream& in, shape& p)
{
p.istream_shape(in);
return in;
}
rectangular.h
#ifndef RECTANGULAR_H
#define RECTANGULAR_H
#include "shape.h"
class rectangular final : public shape
{
private:
double length {0};
double width {0};
public:
rectangular() = default;
rectangular(double length, double width) : length(length), width(width) {}
//void Input() const;
double area() const override;
double perimeter() const override;
void ostream_shape(std::ostream& out) const override;
void istream_shape(std::istream& in) override;
~rectangular() = default;
};
#endif
rectangular.cpp
#include "rectangular.h"
#include <iostream>
double rectangular::area() const
{
return length * width;
}
double rectangular::perimeter() const
{
return (length + width) * 2;
}
void rectangular::istream_shape(std::istream& in)
{
std::cout << "Enter the rectangular length: "; in >> length;
std::cin.ignore();
std::cout << "Enter the rectangular width: "; in >> width;
std::cin.ignore();
}
void rectangular::ostream_shape(std::ostream& out) const
{
out << "Length: " << length << "\t Width: " << width << std::endl;
out << "Area: " << area() << "\tPerimeter: " << perimeter() << std::endl;
}
circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
#include "shape.h"
class circle final : public shape
{
private:
double r{0};
public:
circle() = default;
circle(double r) : r(r) {}
double area() const override;
double perimeter() const override;
void ostream_shape(std::ostream& out) const override;
void istream_shape(std::istream& in) override;
~circle() = default;
};
#endif
circle.cpp
#include "circle.h"
double circle::area() const
{
return 3.14 * r * r;
}
double circle::perimeter() const
{
return 2 * 3.14 * r;
}
void circle::istream_shape(std::istream& in)
{
std::cout << "Enter the circle radius: "; in >> r;
std::cin.ignore();
}
void circle::ostream_shape(std::ostream& out) const
{
out << "Circle radius = " << r << std::endl;
out << "Area: " << area() << "\tPerimeter: " << perimeter() << std::endl;
}
triangle.h
#ifndef TRIANGLE_H
#define TRIANGLE_H
#include "shape.h"
class triangle final : public shape
{
private:
double a {0};
double b {0};
double c {0};
public:
triangle() = default;
triangle(double a, double b, double c) : a(a), b(b), c(c) {}
double area() const override;
double perimeter() const override;
void ostream_shape(std::ostream& out) const override;
void istream_shape(std::istream& in) override;
~triangle() = default;
};
#endif
triangle.cpp
#include "triangle.h"
double triangle::area() const
{
double p = (a + b + c) / 2;
return p*(p-a)*(p-b)*(p-c);
}
double triangle::perimeter() const
{
return a + b + c;
}
void triangle::istream_shape(std::istream& in)
{
std::cout << "Enter the triangle edge a: "; in >> a;
std::cin.ignore();
std::cout << "Enter the triangle edge b: "; in >> b;
std::cin.ignore();
std::cout << "Enter the triangle edge c: "; in >> c;
std::cin.ignore();
}
void triangle::ostream_shape(std::ostream& out) const
{
out << "Triangle edges a= " << a << ", b= " << b << ", c= " << c << std::endl;
out << "Area: " << area() << "\tPerimeter: " << perimeter() << std::endl;
}