studying for a final and decided to build a program which makes use of pure virtual functions and polymorphism. i am stuck on a really weird error maybe i am missing something.
This is the Shape abstract class
#ifndef Shape_hpp
#define Shape_hpp
#include <stdio.h>
#include <string.h>
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
#endif /* Shape_hpp */
The Shape .cpp implementation file
#include "Shape.hpp"
Shape::Shape(const char *shape){
name = shape;
}
The Circle Header file
#ifndef Circle_hpp
#define Circle_hpp
#include "Shape.hpp"
#include <stdio.h>
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
};
#endif /* Circle_hpp */
The circle .cpp implementation file
#include "Circle.hpp"
#include "Shape.hpp"
Circle::Circle(double rad):Shape("Circle"){
m_radius = rad;
}
double Circle::getRadius(){
return m_radius;
}
double Circle::getPerimeter(){
return (2 * 3.14 * m_radius);
}
double getArea(){
return 0;
}
I declared the two pure virtual functions in the abstract "shape" class and am accessing the public of shape class in circle header file, if i declare the pure virtual functions in the circle class it will make it abstract... the error says "Out-of-line definition of 'getPerimeter' does not match any declaration in 'Circle'"
Am i missing something or am i thinking about this the wrong way..
Help would be appreciated. Thanks!
You need to declare all member functions that you define. So in class Circle you need to add:
virtual double getPerimeter();
Or better in C++11:
double getPerimeter() override;
You're defining Circle::getPerimeter() in your .cpp file but there is no member function getPerimeter() in the Circle class declaration. All pure virtual functions need to be overriden in a derived class in order for the class to become concrete. So yes, virtual double getPerimeter(); and override if you're using C++11.
Also, it's good practice to declare simple getters const.
It should be done this way.
class Shape{
const char* name;
public:
Shape(const char* abc);
virtual ~Shape() {} // you should have virtual destructor here
virtual double getPerimeter()=0;
virtual double getArea()=0;
};
class Circle:public Shape{
double m_radius;
public:
Circle(double rad);
double getRadius();
virtual double getPerimeter(); // we need to re-declare it here
virtual double getArea(); // we need to re-declare it here
};
Here's a suggestion. Since Shape is an abstract class, we cannot create objects of the class; so get rid of its constructor. Since we are interested in area and parameter of shapes, define the functions as virtual.
So, here is a redeclaration of Shape class.
#ifndef __SHAPE__
#define __SHAPE__
namespace shape
{
class Shape
{
public:
virtual float getArea()=0;
virtual float getPerimeter()=0;
};
}
#endif
Now, redeclaration of Circle class
#ifndef __CIRCLE__
#define __CIRCLE__
#include "inc/Shape.hpp"
namespace shape
{
class Circle: public Shape
{
float radius;
public:
Circle(float=0.0);
float getArea();
float getPerimeter();
};
}
#endif
Now redefining Circle class
#include "inc/Circle.hpp"
namespace shape
{
Circle::Circle(float radius)
{
this->radius = radius;
}
float Circle::getArea()
{
return ((22/7) * (this->radius * this->radius));
}
float Circle::getPerimeter()
{
return (2 * (22/7) * this->radius);
}
}
Now, in the main class
#include <iostream>
#include "inc/Circle.hpp"
int main()
{
shape::Shape *circle = new shape::Circle(2.5);
std::cout << "Area: " << circle->getArea() << std::endl;
std::cout << "Perimeter: " << circle->getPerimeter() << std::endl;
return 0;
}
You may redeclare the classes without namespaces.
The point to note is that the type of object created should be of the parent class and the object itself should be a child class.
One last thing; all pure virtual functions in the abstract must be redeclared and redefined (overridden) in the derived classes.
Related
I have two base classes, valuationFunction and SimulationEngine where I believe I have created a circular reference that I'm not sure how to sort out. Originally I only had SimulationEngine include ValuationFunction, but then I created the enum RiskFactor in SimulationEngine that I need ValuationFunction to recognize, and that's where I think my trouble stems from. Just looking at this it obviously seems wrong since the two header filers are including each other, but how else would I get the ValuationFunction (and all it's inherited classes) to be able to take an object of type RiskFactor as input?
SimulationEngine :
#pragma once
#define SIMULATION_ENGINE_H
#include "valuationFunction.h"
#include "Wrapper.h"
class SimulationEngine
{
public:
enum RiskFactor { interest_rate, equity, volatility, FX_rate };
SimulationEngine(double horizon, Wrapper<valuationFunction> theFunction_, RiskFactor simulatedRiskFactor);
virtual void DoOnePath(double vol, double normvariate) = 0;
virtual SimulationEngine* clone() const = 0;
const virtual double GetHorizon();
Wrapper<valuationFunction>& GetFunction();
RiskFactor simulatedRiskFactor;
protected:
double horizon;
Wrapper<valuationFunction> theFunction;
};
ValuationFunction:
#pragma once
#define VALUATION_FUNCTION_H
#include "SimulationEngine.h"
class valuationFunction
{
public:
valuationFunction(double TTM);
virtual void ValueInstrument() = 0;
virtual double GetValue() const;
virtual void RiskFactorAdd(double increment, SimulationEngine::RiskFactor simulatedRiskFactor) = 0;
virtual void RiskFactorMultiply(double factor, SimulationEngine::RiskFactor simulatedRiskFactor) = 0;
virtual void UpdateTTM(double timeStep);
virtual valuationFunction* clone() const = 0;
virtual ~valuationFunction() {}
private:
protected:
double f;
double TTM;
};
Create RiskFactor.h. Stick the enum in there. Include it in both headers.
They need to be classes and get area needs to be part of shape, the method getArea needs to be in shape and area needs to be protected and in shape, widght height and radius part of their respective subclass (C++)
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <math.h>
using namespace std;
class shape {
protected:
double area;
public:
double getArea(){return area;};
};
class rectangle:shape {
private:
double width;
double height;
public:
rectangle(){
width=3;
height=4;
}
double getHeight(){return height;};
double getWidth(){return width;};
void setHeight(double h){height=h;};
void setWidth(double w){width=w;};
void setArea(double width, double height){area=height*width;};
};
class circle:shape {
private:
double radius;
public:
circle(){
radius=1;
}
double getRadius(){return radius;};
void setRadius(double r){radius=r;};
void setArea(double width, double height){area=M_PI*(pow(radius,2));};
};
int main () {
rectangle miRectangulo;
circle miCirculo;
cout<<"Area of the rectangle is "<<miRectangulo.getArea()<<endl;
cout<<"Area of the circle is "<<miCirculo.getArea();
return 0;
}
They do need to follow these certain conditions, right now I am getting the error that "double::shape getArea() is inaccesible"
By default, inheritance is private, meaning getArea isn't going to be accessible. Inherit as a public base instead.
class circle: public shape
{
/* snip */
};
I searched through some of the other pages with this same error, but my code does not have any of their issues that I can find. It could just be that I am tired and slightly new to C++, if so sorry.
I have a parent class, shape.h, that has three derived classes; rectangle.h, triangle.h, and circle.h. The parent class is the one that gets the error "Redefinition of 'Shape'" on the third line. For the life of me I can not figure out what is wrong, other than possible the way I call the shape constructors from the derived classes. Please help, anymore information you need just let me know.
Shape.h:
#include < cmath>
class Shape
{
public:
//constructors
Shape();
Shape(float a);
Shape(float a, float b);
//Returns
float area();
float perimeter();
protected:
float base;
float height;
float radius;
};
Shape.cpp:
#include "Shape.h"
//constructors
Shape::Shape()
{
base = 0;
height = 0;
radius = 0;
}
Shape::Shape(float a)
{
radius = a;
}
Shape::Shape(float a, float b)
{
base = a;
height = b;
}
//returns
float Shape::area()
{
return 0;
}
float Shape::perimeter()
{
return 0;
}
All derived classes are the same except different calculations , so here is Circle.h:
#include "Shape.h"
class Circle: public Shape
{
public:
//constructors
Circle();
Circle(float a);
//Returns
float area();
float perimeter();
private:
};
Circle.cpp:
#include "Circle.h"
//constructors
Circle::Circle():Shape()
{
}
Circle::Circle(float a):Shape(a)
{
}
//returns
float Circle::area()
{
return (3.14 * pow(radius,2));
}
float Circle::perimeter()
{
return (2 * 3.14 * radius);
}
In Circle.cpp Shape.h indirectly included twice and causes mentioned compilation error.
Add include guard to your headers. E.g. Shape.h should be:
#ifndef SHAPE_H
#define SHAPE_H
// Put your Shape class here
#endif
The other approach is to use #pragma once at the beggining of Shape.h if your compiler supports it.
I keep getting this error message every time I try to compile my shape.h file:
Previous Declaration of 'class shape'. Base class not declared correctly?
The shape.h header file:
#include <iostream>
/*
1. class Shape will have virtual functions called area() and perimeter()
2. derived classes will encapsulate dimensions of the sides or radius depending on class used
3. derived classes will have default constructors as well as overloaded constructors to initialize dimensional values
4. each derived class will have own area and perimeter functions that will be used in polymorphic manner
5. write class headers, implementations, and test files separately
*/
class shape //parent class
{
public:
shape();
virtual int area();
virtual int perimeter();
};
This is implementation of the parent class shape.cpp:
#include "shape.h"
#include<iostream>
using namespace std;
shape::shape(){}
This is the derived class declaration of shape rectangle.h:
#include "shape.h"
class rectangle: public shape
{
public:
rectangle();//constructor
rectangle(int l, int w ); //stands for length and width
int perimeter(int, int); //function shared w/shape parent class
int area(int, int); //function shared w/shape parent class
private:
int longside, wideside;
};
This is the implementation for rectangle class rectangle.cpp:
#include "rectangle.h"
rectangle::rectangle(){}
rectangle::rectangle(int l, int w)
{
longside = l;
wideside=w;
};
int rectangle::area(int wideside, int longside)
{
int totarea;
totarea = (wideside*longside);
return totarea;
};
int rectangle::perimeter(int side1, int side2)
{
int perim = ((wideside)+(longside));
return perim;
};
This is the test file testfile.cpp:
#include <iostream>
#include "shape.h"
#include "rectangle.cpp"
using namespace std;
int main()
{
rectangle rect1;
int side1, side2;
cout<<"\n Find Area of an Rectangle" << endl;
cout<<"\nChoose a length for sides 1 abd 2" << endl;
cout<<"\nSide 1: "<< endl;
cin >> side1;
cout<<"\nSide 2: "<< endl;
cout<<"\nRectangle's Area is: "<< rect1.area( side1, side2 ) << endl;
cout<<"\nRectangle's Perimeter is: "<<rect1.perimeter( side1, side2 )<< endl;
return 0;
}
The class shape is a base class for other shape objects. I'm just testing out functionality with a derived class called class rectangle. Aren't I supposed to make a header file every time a class is defined? I included all of my files from this program to see if that would help.
I am trying to develop abstract design pattern code for one of my project as below.. But, I am not able to compile the code ..giving some compile errors(like "unresolved external symbol "public: virtual void __thiscall Xsecs::draw_lines(double,double)" (?draw_lines#Xsecs##UAEXNN#Z)" ).. Can any one please help me out in this...
#include "stdafx.h"
#include <iostream>
#include <vector>
#include "Xsecs.h"
using namespace std;
//Product class
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2);
virtual void draw_curves(double pt1, double rad);
};
class polyline: public Xsecs
{
public:
virtual void draw_lines(double pt1,double pt2)
{
cout<<"draw_line in polygon"<<endl;
}
virtual void draw_curves(double pt1, double rad)
{
cout<<"Draw_curve in circle"<<endl;
}
/*void create_polygons()
{
cout<<"create_polygon_thru_draw_lines"<<endl;
}*/
};
class circle: public Xsecs
{
public:
virtual void draw_lines(double pt1,double pt2)
{
cout<<"draw_line in polygon"<<endl;
}
virtual void draw_curves(double pt1, double rad)
{
cout<<"Draw_curve in circle"<<endl;
}
/*void create_circles()
{
cout<<"Create circle"<<endl;
}*/
};
//Factory class
class Factory
{
public:
virtual polyline* create_polyline()=0;
virtual circle* create_circle()=0;
};
class Factory1: public Factory
{
public:
polyline* create_polyline()
{
return new polyline();
}
circle* create_circle()
{
return new circle();
}
};
class Factory2: public Factory
{
public:
circle* create_circle()
{
return new circle();
}
polyline* create_polyline()
{
return new polyline();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Factory1 f1;
Factory * fp=&f1;
return 0;
}
I presume you were attempting to create a virtual base class. You need to add '= 0' to the end of the draw_lines and draw_curves methods in the class Xsecs
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2) = 0;
virtual void draw_curves(double pt1, double rad) = 0;
};
the compiler is complaining as you haven't any implementation for the methods in question.
You should inherit publicly from A, like
class ProductA1 : public ProductA {
...
Without the public keyword, this relationship is private inheritance, which is not an is-a relationship, therefore you can't simply cast from ProductA1 to ProductA.
Scott Meyers explains this in Effective C++, Third Ed., Item 39:
[...] compilers, when given a hierarchy in which a class Student publicly inherits from a class Person, implicitly convert Students to Persons when that is necessary for a function call to succeed.
[...] the first rule governing private inheritance you've just seen in action: in contrast to public inheritance, compilers will generally not convert a derived class object (such as Student) into a base class object (such as Person) if the inheritance relationship between the classes is private. [...] The second rule is that members inherited from a private base class become private members of the derived class, even if they were protected or public in the base class.
Private inheritance means is-implemented-in-terms-of. If you make a class D privately inherit from a class B, you do so because you are interested in taking advantage of some of the features available in class B, not because there is any conceptual relationship between objects of types B and D. As such, private inheritance is purely an implementation technique.
Update for the 2nd version of the post: if you want pure virtual functions, you should declare them so:
virtual void draw_lines(double pt1, double pt2) = 0;
virtual void draw_curves(double pt1, double rad) = 0;
Otherwise the linker will miss their definition.
In all your class definitions you forgot to use the public keyword :
class ProductA1 : ProductA
should be
class ProductA1 : public ProductA
and so on
You either need to add an implementation for Xsecs::draw_lines / Xsecs::draw_curves, or define them as pure virtual, by appending "= 0" to their definition.
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2)
{
// Do something
}
virtual void draw_curves(double pt1, double rad)
{
// Do something
}
};
Or...
class Xsecs
{
public:
virtual void draw_lines(double pt1, double pt2) = 0;
virtual void draw_curves(double pt1, double rad) = 0;
};
change "class" to "struct" this make the default public inheritance rather than private