pure virtual method

M

mfabricius

Hi,

I am probably trying to do something really stupid.

There is a class shape:

class Shape
{
public:
Shape();
virtual ~Shape();
....
virtual bool inside(prec_t x, prec_t y) = 0;
....
virtual Shape * copy() = 0;
....
};

and a class circle which is derived from shape

class Circle : public Shape
{
public:
Circle(prec_t radius);
Circle(prec_t radius, prec_t outerRadius);
Circle();
virtual ~Circle();

....
bool inside(prec_t x, prec_t y);
....
Shape * copy();
....
};

ok, now the class Surface has a member of type Shape *:

class Surface
{
public:
....
Shape* myShape;
....
}


finally the last class derives from Surface:
class EvenASph : public Surface
{
public:
....
Surface outerShell;
Surface lowerShell;
....
}

now in this class I am trying to do something like

1) upperShell.shape = this->shape->copy();
2) lowerShell.shape = this->shape->copy();

this seems to work, the compiler does not complain.
But I occasionally encountered crashes when I call
upperShell.shape->inside()

Occasionally meaning, either it does not work at all -
the program immediately causes a Segmentation fault -
or it just work fine and never crashes.
I used the compiler g++ 4.0.3.


If instead of 1 and 2) I do, for example
lowerShell.shape = this->shape

I always get an error when trying to execute:

pure virtual method called
terminate called without an active exception


Am I trying to do something really illegal?



Thanks,

Maximilian
 
G

Gianni Mariani

pure virtual method called
terminate called without an active exception


Am I trying to do something really illegal?

It sounds like an order of construction/destruction issue. I can't tell
with the code you wrote. It would be good to write a smaller
chunk-o-code that shows the problem.
 
I

Ian Collins

I always get an error when trying to execute:

pure virtual method called
terminate called without an active exception


Am I trying to do something really illegal?
You aren't doing something daft like calling a virtual method from a
constructor are you?
 
V

Victor Bazarov

I am probably trying to do something really stupid.
[..]
I always get an error when trying to execute:

pure virtual method called
terminate called without an active exception


Am I trying to do something really illegal?

Calling a pure virtual function is not illegal, it just has
undefined behaviour.

In addition to other's suggestions, check if any of your objects
are passed by value instead of by reference. That would cause
slicing. Basically, put a breakpoint in the constructor of your
abstract base class and see if it's ever called *not* from the
constructor of the derived class.

V
 
M

mfabricius

You aren't doing something daft like calling a virtual method from a
constructor are you?

Hi all,

by implementing the example, I think I found my mistake.

Thanks for the replies,

Maximilian
 
B

BobR

Hi,
I am probably trying to do something really stupid.
There is a class shape:

class Shape{ public:
Shape();
virtual ~Shape();
...
virtual bool inside(prec_t x, prec_t y) = 0;
...
virtual Shape * copy() = 0;
...
};

You might want to 'define' those pure virtuals for testing.

bool Shape::inside( prec_t x, prec_t y){
std::cerr<<"base virtual \"Shape::inside()\" called"<<std::endl;
return false;
}

Shape* Shape::copy(){
std::cerr<<"base virtual \"Shape::copy()\" called"<<std::endl;
return this;
}

..... because of this:

class Surface{ public: ...
Shape* myShape; // <--------! slice if set to a derived?
}; // ADD the semicolon!!!

1) upperShell.shape = this->shape->copy();

There is no 'upperShell' in the incomplete code you showed.
There is no 'shape' in the incomplete code you showed.
( did you mean 'myShape'? )

You also failed to show the definitions for:
Circle::inside()
Circle::copy()

FAQ http://www.parashift.com/c++-faq-lite
 
M

mfabricius

So, what was the mistake?

Thank you guys for all the very useful suggestions!
Of course in the end is turned out to be my stupidity:
Is said I did

1) upperShell.shape = this->shape->copy();
2) lowerShell.shape = this->shape->copy();

what I did not say is that I deleted the obeject which these two
pointers were pointing two:
delete upperShell.shape; //I guess, this you really
have to do
1) upperShell.shape = this->shape->copy();
delete upperShell.shape; //whereas this was a
mistake, uppershell now should have been
// lowershell.
2) lowerShell.shape = this->shape->copy();


Thanks again everybody!

Maximilian
 
T

tragomaskhalos

class Shape
{
...
virtual Shape * copy() = 0;
...
};

class Circle : public Shape
{
...
Shape * copy();
};

Not directly related to your question,
but in case you didn't know, you could
declare Circle's copy as:
Circle* copy();
This can often eliminate casting from the
calling code. (google for "covariant return
type").
 
A

anon

Thank you guys for all the very useful suggestions!
Of course in the end is turned out to be my stupidity:
Is said I did

1) upperShell.shape = this->shape->copy();
2) lowerShell.shape = this->shape->copy();

what I did not say is that I deleted the obeject which these two
pointers were pointing two:
delete upperShell.shape; //I guess, this you really
have to do
1) upperShell.shape = this->shape->copy();
delete upperShell.shape; //whereas this was a
mistake, uppershell now should have been
// lowershell.
2) lowerShell.shape = this->shape->copy();

Thats why you need to post minimal compilable source that represents the
problem. This is not even shown on your starting post.
Doing so, you might even find a cause of the problem yourself.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,140
Latest member
SweetcalmCBDreview
Top