It seems only be a problem with circle.cpp even if the code looks the same in point.cpp. I've been looking at the code a long time now and I haven't found anything different in the two files. Here is the error message:
>------ Build started: Project: ou5, Configuration: Release Win32 ------
1> circle.cpp
1> ou5.cpp
1>c:\users\jonas\documents\visual studio 2010\projects\ou5\ou5\shapeptr.h(52): error C2259: 'Shape' : cannot instantiate abstract class
1> due to following members:
1> 'Shape *Shape::clone(void) const' : is abstract
1> c:\users\jonas\documents\visual studio 2010\projects\ou5\ou5\shape.h(21) : see declaration of 'Shape::clone'
1>ou5.cpp(20): error C2259: 'Shape' : cannot instantiate abstract class
1> due to following members:
1> 'Shape *Shape::clone(void) const' : is abstract
1> c:\users\jonas\documents\visual studio 2010\projects\ou5\ou5\shape.h(21) : see declaration of 'Shape::clone'
1>ou5.cpp(27): error C2259: 'Shape' : cannot instantiate abstract class
1> due to following members:
1> 'Shape *Shape::clone(void) const' : is abstract
1> c:\users\jonas\documents\visual studio 2010\projects\ou5\ou5\shape.h(21) : see declaration of 'Shape::clone'
1> point.cpp
1> polygon.cpp
1> rectangle.cpp
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The code for the base class with a pure virtual function:
#ifndef SHAPE_H
#define SHAPE_H
using namespace std;
#include <iostream>
#include <ostream>
class Shape
{
public:
Shape()
{
cout << "Shape constructor" << endl;
}
Shape(double xval, double yval)
{
x = xval;
y = yval;
}
virtual Shape* clone() const = 0;
virtual double area()
{
return 1;
}
virtual void print() const{}
virtual ostream& printf(ostream &os){return os;}
/* // Copy constructor
Shape(const Shape *sp)
{
// Copy the string into our newly allocated memory
sp =this->clone();
}*/
/*Shape & operator=(const Shape & sptr)
{
if(this!= &sptr)
{
*this = sptr.clone();
}
return *this;
}*/
double getx() const
{
return x;
}
double gety() const
{
return y;
}
virtual ~Shape() {cout << "Shape raderas av destruktor" <<endl; }
protected:
double x; //Attribut
double y; //Attribut
Shape *sp;
};
#endif
Point.h that is working:
#ifndef POINT_H
#define POINT_H
#include "shape.h"
using namespace std;
#include <iostream>
#include <fstream>
class Point : public Shape
{
public:
Point()
{
cout << "Point constructor" << endl;
}
Point(double x, double y, double sz) : Shape(x,y), size(sz)
{
cout << "Point constructor" << endl;
}
void las(istream &is)
{
is >> x >> y >> size;
}
ostream& printf(ostream &os) ;
void print() const;
double area();
Shape* clone() const;
virtual ~Point(){cout << "Point raderas av destruktor" << endl;}
private:
double size; //Attribut
};
#endif
point.cpp:
#include "point.h"
#include <ostream>
using namespace std;
Shape* Point::clone() const { return new Point( *this); }
void Point::print() const
{
cout << "POINT: ";
cout <<"(" << this->x<<"," << this->y << ")" << this->size << endl;
}
ostream& Point::printf(ostream &os)
{
os << "POINT: ";
os <<"(" << this->x<<"," << this->y << ")" << this->size << endl;
return os;
}
double Point::area()
{
return size;
}
The files with a problem. First circle.h:
#ifndef CIRCLE_H
#define CIRCLE_H
#include "shape.h"
using namespace std;
#define M_PI 3.141592654
#include <fstream>
#include <iostream>
class Circle : public Shape
{
public:
Circle()
{
cout << "Circle constructor" << endl;
}
Circle(double x, double y, double rad) : Shape(x,y), radie(rad)
{
cout << "Circle constructor" << endl;
}
void las(istream &is)
{
is >> x >> y >> radie;
}
ostream& printf(ostream &os);
double area();
void print() const;
Shape* clone() const;
virtual ~Circle(){cout << "Circle raderas av destruktor" << endl;}
private:
double radie; //Attribut
};
#endif
Then circle.cpp:
#include "circle.h"
using namespace std;
#include <ostream>
Shape* Circle::clone() const {return new Circle( *this);}
double Circle::area()
{
double tmparea;
tmparea = M_PI * radie * radie;
return tmparea;
}
void Circle::print() const
{
cout << "CIRCLE: ";
cout <<"(" << this->x<<"," << this->y << ")" << this->radie << endl;
}
ostream& Circle::printf(ostream &os)
{
os << "CIRCLE: ";
os <<"(" << this->x<<"," << this->y << ")" << this->radie << endl;
return os;
}
The problem is with clone
and it looks the same in the file working and the not working file. The working file is point.cpp
but it also works with two other files not posted here.
I add shapeptr.h here:
#ifndef SHAPEPTR_H
#define SHAPEPTR_H
#include "shape.h"
#include "circle.h"
#include "point.h"
#include "polygon.h"
#include "rectangle.h"
#include <ostream>
#include <istream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
class ShapePtr
{
public:
ShapePtr()
{
sptr = 0;
numshapes = numshapes + 1;
}
ShapePtr(Shape * v)//: Shape(v->getx(),v->gety())
{
sptr = v;
numshapes = numshapes + 1;
}
// Copy constructor
ShapePtr(const Shape &sp)
{
// Copy the string into our newly allocated memory
sptr = sp.clone();
}
const ShapePtr & ShapePtr::operator=(const Shape & sp)
{
if(this->sptr!= &sp)
{
sptr = sp.clone();
}
return *this;
}
~ShapePtr(){
numshapes = numshapes - 1;
cout << "ShapePtr raderas av destruktor" << endl;
}
Shape getshape()
{
return *sptr;
}
private:
Shape *sptr;
public:
static int numshapes;
friend istream& operator>>(istream &is, ShapePtr & sp);
friend ostream& operator<<(ostream &os, const ShapePtr & sp);
};
int ShapePtr::numshapes = 0;
ostream& operator<<(ostream &os, const ShapePtr & sp)
{
os << sp.sptr->printf(os);
return os;
}
istream& operator>>(istream &is, ShapePtr & sp)
{
string check;
while(!is.eof())
{
is >> check;
if(check == "Circle")
{
Circle cir;
cir.las( is );
sp = ShapePtr(new Circle(cir));
return is;
}
if(check == "Polygon")
{
Polygon pol;
pol.las( is );
sp = ShapePtr(new Polygon(pol));
return is;
}
if(check == "Point")
{
Point poi;
poi.las( is );
sp = ShapePtr(new Point(poi));
return is;
}
if(check == "Rectangle")
{
Rectangle rec;
rec.las( is );
sp = ShapePtr(new Rectangle(rec));
return is;
}
}
}
#endif