-3

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
  • 2
    The error is in `shapeptr.h`. – juanchopanza May 09 '13 at 14:24
  • 1
    You should not put "using namespace std;" in an include file. It brings in the whole std namespace to anyone trying to use your .h file. – MikMik May 09 '13 at 14:34
  • The code as you have posted seems to compile for me. Did you copy-paste it exactly? What was the error message? Secondly let me strongly reiterate what @MikMik said: Never use `using` in headers (there may be exceptions, for example within inline methods but don't worry about that). – Mark B May 09 '13 at 14:44
  • I did copy and paste exactly – user2224247 May 09 '13 at 15:00
  • Shapeptr.h is just trying to make an instance of an abstract class. The problem is probably not there. – user2224247 May 09 '13 at 15:03
  • But it is not abstract since it's implemented in circle.cpp. The same function is implemented in point.cpp and no error comes for that one. – user2224247 May 09 '13 at 15:17
  • @user2224247 `Circle` is a different `type` than `Shape` so you can create an instance of `Circle` because it is `concrete` and does not have any abstract methods. This may be helpul http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr142.htm – Shafik Yaghmour May 09 '13 at 15:20
  • The base class is Shape and the two derived classes Point and Circle and actually two more. Point works fine but not Circle. – user2224247 May 09 '13 at 15:23
  • @user2224247 To remove confusion, the terms for `Circle` and `Point` are concrete classes and `Shape` is an abstract class. I think seeing `Shapeptr.h` will make the problem clear otherwise I don't think we can help more and most likely it will garner votes to close. – Shafik Yaghmour May 09 '13 at 15:28
  • @juanchopanza In case you are curious the problem was indeed in `shapeptr.h` – Shafik Yaghmour May 09 '13 at 16:27
  • What was it? Thank You! – user2224247 May 09 '13 at 16:30

1 Answers1

1

Based on your comments you are attempting to make an instance of an abstract class in Shapeptr.h which is not valid. The point where you attempt to create this instance is here:

Shape getshape()
{
     return *sptr;
}

As Mark B. pointed out the fix is to change the return type to Shape&.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740