コードが point.cpp で同じように見えても、circle.cpp だけの問題のようです。私は長い間コードを見てきましたが、2 つのファイルに違いは見つかりませんでした。エラーメッセージは次のとおりです。
>------ 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 ==========
純粋仮想関数を持つ基本クラスのコード:
#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:
#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
ポイント.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;
}
問題のあるファイル。最初の 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
次に 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;
}
問題は、clone
動作中のファイルと動作していないファイルで同じように見えます。作業ファイルはありますがpoint.cpp
、ここに掲載されていない他の 2 つのファイルでも動作します。
ここに shapeptr.h を追加します。
#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