By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,184 Members | 1,502 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,184 IT Pros & Developers. It's quick & easy.

Standard C++ design question--- geometry class

P: n/a
Jon
Hello all,

I'm certain this question has been asked before; I was unsure what
terms to search for within the newsgroup archive to find the proper
answer I wanted. Hopefully someone can point me to some relevant
postings or websites.

In any case, I want to create a geometry class that has some base
functionalities. The problem I am particularly interested in is such:

(the classes are empty for clarity of problem; assume standard
constructors and (virtual) destructors exist; and for protected or
private class members, standard get() and set() methods exist)

class Vec3; // 3-element vector

class Geometry {};

class Point : public Geometry
{
public:
Point( const Vec3f &v ) : Geometry(), _vertex(v) {}
protected:
Vec3 _vertex; // 3D location of point
};

class Curve : public Geometry
{
public:
virtual void appendPt( const Vec3f& ) = 0;
protected:
vector<Point*> _controlPts;
};

class Surface : public Geometry {};
class Volume : public Geometry {};

class BezierPoint : public Point
{
public:
BezierPoint( const Vec3f &v ) :
Point(v), _frontHandle(v), _backHandle(v)
{}
protected:
/// these members are used to determine shape of the curve
Vec3 _frontHandle; // 3D location of "front" handle
Vec3 _backHandle; // 3D location of "back" handle
}

// a connected series of lines
class Polyline : public Curve
{
public:
void appendPt( const Vec3f &v )
{ _controlPts.push_back( new Point( v )); }
};
// bezier curve
class Bezier : public Curve
{
public:
void appendPt( const Vec3f &v )
{ _controlPts.push_back( new BezierPoint( v )); }
};
Now, the problem:

I want to add iterator methods that return pointers to the proper
Point object, but I want the returned object to be the correct type:
in other words, if I had a begin() method that returns the first point
in the curve, Polyline::begin() should return a Point* and
Bezier::begin() return a BezierPoint*.

At the same time, I don't want to have to explicitly cast any given
Curve into the proper type before calling begin().

Is there a way to do this?

I initially thought Curve should have a pure virtual function Point*
begin() = 0, but then subclasses (namely Bezier) can't override the
return type.

The solution I'm using now is have Curve contain all the iterator
methods and always returning Point pointers, but when I deal with
bezier curves I hate constantly having to do
dynamic_cast<BezierPoint*>(bezierCurve.begin()), especially when I
want to iterate through all the points to draw the curve, for example.

I hope this made sense. I would appreciate any feedback.

Regards,
Jon
Jul 19 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"Jon" <in******@mit.edu> wrote...
[...] I want to create a geometry class that has some base
functionalities. The problem I am particularly interested in is such:

(the classes are empty for clarity of problem; assume standard
constructors and (virtual) destructors exist; and for protected or
private class members, standard get() and set() methods exist)

class Geometry {};

class Point : public Geometry
{ [...] };

class Curve : public Geometry
{ [...]
vector<Point*> _controlPts; };

class BezierPoint : public Point
{ [...] }

// a connected series of lines
class Polyline : public Curve
{ [...] };
// bezier curve
class Bezier : public Curve
{ [...] };
Now, the problem:

I want to add iterator methods that return pointers to the proper
Point object, but I want the returned object to be the correct type:
in other words, if I had a begin() method that returns the first point
in the curve, Polyline::begin() should return a Point* and
Bezier::begin() return a BezierPoint*.

At the same time, I don't want to have to explicitly cast any given
Curve into the proper type before calling begin().

Is there a way to do this?
If the Bezier's container of points will really contain pointers to
'BezierPoint', you don't need to do anything, the pointers from the
vector will be pointers to the objects you created, and if you create
BezierPoints for a Bezier object to insert into the vector, the same
objects will be returned.
I initially thought Curve should have a pure virtual function Point*
begin() = 0, but then subclasses (namely Bezier) can't override the
return type.
There is no need.
The solution I'm using now is have Curve contain all the iterator
methods and always returning Point pointers, but when I deal with
bezier curves I hate constantly having to do
dynamic_cast<BezierPoint*>(bezierCurve.begin()), especially when I
want to iterate through all the points to draw the curve, for example.


You don't need to. Just make sure 'Point' has all functions necessary
for you to obtain coordinates, etc., to draw the curve.

Victor
Jul 19 '05 #2

P: n/a
> I want to add iterator methods that return pointers to the proper
Point object, but I want the returned object to be the correct type:
in other words, if I had a begin() method that returns the first point
in the curve, Polyline::begin() should return a Point* and
Bezier::begin() return a BezierPoint*.

At the same time, I don't want to have to explicitly cast any given
Curve into the proper type before calling begin().

Is there a way to do this?


There _are_ covariant return types in C++ :

class Point {};
class BezierPoint : public Point {};

class Curve
{
public:
virtual Point* begin();
};

class Polyline : public Curve
{
public:
Point* begin();
};

class Bezier : public Curve
{
public:
BezierPoint* begin();
};

As long as the return types are covariant (that is, in the same
hierarchy), it runs fine.
Jonathan
Jul 19 '05 #3

P: n/a
Jon
> There _are_ covariant return types in C++ :

This is the answer I was looking for, and I thought C++ had this
feature.

BUT when I try to compile (I'm using Microsoft Visual Studio's nmake
and cl) I get an error like:

..\Bezier.h(78) : error C2555: 'Bezier::begin' : overriding virtual
function differs from 'Curve::begin' only by return type or calling
convention

Am I missing something?

Thanks,
Jon
Jul 19 '05 #4

P: n/a
Jon
my apologies for filling your inboxes with my last reply (and this one
too).

i did some quick research in the archives---i didn't realize the term
was "covariance". in any case, i found out it's not my fault but
microsoft's. grr.

thanks,
jon
Jul 19 '05 #5

P: n/a
> > There _are_ covariant return types in C++ :

This is the answer I was looking for, and I thought C++ had this
feature.

BUT when I try to compile (I'm using Microsoft Visual Studio's nmake
and cl) I get an error like:

.\Bezier.h(78) : error C2555: 'Bezier::begin' : overriding virtual
function differs from 'Curve::begin' only by return type or calling
convention

Am I missing something?


No, vc++ is.
Jonathan
Jul 19 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.