Reputation: 1
I am new at C++, and have some problems with it. I would like to create an abstract class, and two more abstract classes that inherit from that class. Finally, those two classes are used to be implemented by concrete classes. Here are my header and source files:
/*
* Cylinder.h
*/
#ifndef CYLINDER_H_
#define CYLINDER_H_
class Shape{
public:
virtual ~Shape();
virtual const double area()=0;
virtual const void printDetails();
};
class Shape2D: virtual public Shape{
public:
virtual const double scope()=0;
};
class Shape3D: virtual public Shape{
public:
virtual const double volume()=0;
};
class Rectangle: public Shape2D{
private:
double a;
double H;
public:
Rectangle();
Rectangle(double a, double H);
Rectangle(Rectangle &r);
double getA() const;
double getH() const;
void setA(double a);
void setH(double H);
};
class Circle: public Shape2D{
private:
double r;
public:
Circle();
Circle(double r);
Circle(Circle &c);
double getR() const;
void setR(double r);
};
class Cylinder: public Shape3D{
private:
Circle base;
Rectangle wrapper;
public:
Cylinder();
Cylinder(Rectangle &r, Circle &c);
Cylinder(double a, double H, double r);
Cylinder(Cylinder &c);
double getHeight() const;
double getBaseRadius() const;
double getBaseArea() const;
double getBaseScope() const;
double getWrapperArea() const;
double getWrapperScope() const;
void setHeight(double H);
void setRadius(double r);
Rectangle* getWrapper() const;
Circle* getBase() const;
};
#endif /* CYLINDER_H_ */
/*
* Cylinder.cpp
*/
#include <iostream>
#include "Cylinder.h"
#include <math.h>
using namespace std;
void Shape2D::printDetails() const{
cout<<"\nArea: "<<area();
cout<<"\nScope: "<<scope();
}
void Shape3D::printDetails() const{
cout<<"\nArea: "<<area();
cout<<"\nVolume: "<<volume();
}
Rectangle::Rectangle(){
H=0.0;
a=0.0;
}
Rectangle::Rectangle(double a, double H){
this->H=H;
this->a=a;
}
Rectangle::Rectangle(Rectangle &r){
a=r.a;
H=r.H;
}
Rectangle::~Rectangle(){
cout<<"Rectangle deallocated.";
}
double Rectangle::getA() const{
return a;
}
double Rectangle::getH() const{
return H;
}
void Rectangle::setA(double a){
this->a=a;
}
void Rectangle::setH(double H){
this->H=H;
}
double Rectangle::scope() const{
return 2*a+2*H;
}
double Rectangle::area() const{
return a*H;
}
void Rectangle::printDetails() const{
cout<<"\nDimensions of rectangle: "<<a<<"*"<<H;
Shape::printDetails();
}
Circle::Circle(){
r=0.0;
}
Circle::Circle(double r){
this->r=r;
}
Circle::Circle(Circle &c){
r=c.r;
}
Circle::~Circle(){
cout<<"Circle deallocated.";
}
double Circle::getR() const{
return r;
}
void Circle::setR(double r){
this->r=r;
}
double Circle::scope() const{
return 2*r*M_PI;
}
double Circle::area() const{
return r*r*M_PI;
}
void Circle::printDetails() const{
cout<<"\nRadius of circle: "<<r;
Shape::printDetails();
}
Cylinder::Cylinder(){
wrapper=new Rectangle(0.0,0.0);
base=new Circle(0.0);
}
Cylinder::Cylinder(Rectangle &r, Circle &c){
base=c;
wrapper=r;
}
Cylinder::Cylinder(double a=0.0, double H=0.0, double r=0.0){
wrapper=new Rectangle(a,H);
base=new Circle(r);
}
Cylinder::Cylinder(Cylinder &c){
c.base=new Circle(c.base);
c.wrapper=new Rectangle(c.wrapper);
}
Cylinder::~Cylinder(){
delete base;
delete wrapper;
}
double Cylinder::getHeight() const{
return wrapper.getH();
}
double Cylinder::getBaseRadius() const{
return base.getR();
}
double Cylinder::getBaseArea() const{
return base.area();
}
double Cylinder::getBaseScope() const{
return base.scope();
}
double Cylinder::getWrapperArea() const{
return wrapper.area();
}
double Cylinder::getWrapperScope() const{
return wrapper.scope();
}
void Cylinder::setHeight(double H){
wrapper.setH(H);
}
void Cylinder::setRadius(double r){
base.setR(r);
wrapper.setA(2*base.getR()*M_PI);
}
double Cylinder::volume() const{
return base*wrapper.getH();
}
double Cylinder::area() const{
return 2*base.area+wrapper.area;
}
void Cylinder::printDetails() const{
cout<<"\nRadius of base of Cilynder: "<<base.getR();
cout<<"\nHeight of wrapper: "<<wrapper.getH();
Shape::printDetails();
}
Rectangle* Cylinder::getWrapper() const{
return new Rectangle(wrapper);
}
Circle* Cylinder::getBase() const{
return new Circle(base);
}
My compiler gives me different errors as I try to modify the code to accomplish somehow to have classes Rectangle, Circle and Cylinder as non abstract ones. I am not sure where should I put method definitions (should they be duplicated in inherited classes), and what is their proper form actually. Sorry for long text. I hope someone can help me. Thanks in advance
Sam
Upvotes: 0
Views: 1604
Reputation: 24115
You aren't implementing the pure virtual methods. Whenever you have pure virtual methods (virtual void whatever()=0
), that makes the class abstract. Abstract classes can not be instantiated. In order to be instantiated, concrete subclasses must implement all the pure virtual methods from ancestor classes.
For example, Rectangle
is missing the scope
method inherited from Shape2D
, and the area
method inherited from Shape
. That will cause errors along the lines of "can't instantiate Rectangle class because it is abstract." It looks like you have the implementations of those methods lower in the file, but they aren't declared anywhere inside the Rectangle
class.
Upvotes: 6