Why do we need non-virtual destructor?

N

Neelesh Bodas

Alex said:
Why do we need non-virtual destructor?
Because of vtable?

What exactly are you asking?

The destructor should be virtual if the class is polymorphic, so that
you can properly delete the derived class's object through pointer to
the base class.

If the class is not polymorphic (and hence not intended to be used as
base class) then destructor should be non-virtual.
 
M

Mateusz Loskot

Alex said:
If are there situations that we _must_ use _non-virtual_ destructor?

Most...

Why would you expect to use Point class as a base?

class Point
{
public:
Point(double x, double y) : _x(x), _y(y) {}
~Point()
//...
private:
double _x;
double _y;
}

There are plenty of non-polimorphic classes, classes used in OOP
constructions (i.e. design patterns) where you don't expect to use
inheritance. So, in such cases you don't use virtual constructors
(virtual methods, in general).
 
M

Mateusz Loskot

Mateusz said:
There are plenty of non-polimorphic classes, classes used in OOP
constructions (i.e. design patterns) where you don't expect to use
inheritance.

I mean "where you don't expect to use" as "where, in some cases, you
don't need inheritance".
 
N

Neelesh Bodas

Alex said:
If are there situations that we _must_ use _non-virtual_ destructor?

Well, if, by "must" you mean syntactic correctness, then no, C++
doesnot ever enforce that from the syntactic angle.
But if you are talking about good techniques of writing code ( logical
correctness), then any class which is _not_ supposed to act as a base
class should have a public non-virtual destructor. But note that its
not again a _must_ : rather, it is a coding technique that one should
always follow.
 
R

Risto Lankinen

Mateusz Loskot said:
Why would you expect to use Point class as a base?

Many reasons, really! For instance, a mouse cursor position is a Point.

- Risto -
 
B

Ben Pope

public base!
Many reasons, really! For instance, a mouse cursor position is a Point.

Composition would probably make more sense than public inheritance.

Why would you want to access points polymorphically?

Ben Pope
 
R

Risto Lankinen

Ben Pope said:
Why would you want to access points polymorphically?

* I have a set of functions that manipulate points. Examples:

Distance operator-( const Point &,const Point & );
Distance operator/( const Distance &,int );
Point operator+( const Point &,const Distance & );
Point operator+( const Distance &,const Point & );

* Class Point has a virtual assignment operator.

Then, for example, the following function...

void CenterToRect( Point &pt,const Rectangle &rc )
{
pt = rc.TopLeft() + (rc.BottomRight()-rc.TopLeft())/2;
}

.... could be called as...

CenterToRect( the_cursorpos,a_window );

.... and magically the mouse cursor is centered wrt/ the window.

This cannot be done polymorphically if a Point is but contained
by the class CursorPos.

- Risto -
 
G

Guest

Risto said:
* I have a set of functions that manipulate points. Examples:

Distance operator-( const Point &,const Point & );
Distance operator/( const Distance &,int );
Point operator+( const Point &,const Distance & );
Point operator+( const Distance &,const Point & );

* Class Point has a virtual assignment operator.

Then, for example, the following function...

void CenterToRect( Point &pt,const Rectangle &rc )
{
pt = rc.TopLeft() + (rc.BottomRight()-rc.TopLeft())/2;
}

... could be called as...

CenterToRect( the_cursorpos,a_window );

... and magically the mouse cursor is centered wrt/ the window.

This cannot be done polymorphically if a Point is but contained
by the class CursorPos.

Yes, it can be done using composition even better:

class Point
{
double _x;
double _y;
public:
Point(double x, double y) : _x(x), _y(y) {}
};

class Cursor
{
Point pt;
public:
Center(const Rectangle& rc)
{
pt = rc.TopLeft() + (rc.BottomRight() - rc.TopLeft()) / 2;
}
};

Cheers
 
R

Risto Lankinen

Yes, it can be done using composition even better:

Your example doesn't do the same thing. In particular, it does not
move the mouse cursor to the designated point.

Let me elaborate:

struct Point
{
virtual void Get( int &,int & ) = 0;
virtual Point &operator=( const Point & ) = 0;
virtual ~Point() { }
};

struct PointXY : Point
{
int x;
int y;
PointXY( int x,int y ) x(x) , y(y) { }
PointXY( const Point &pt ) { pt.Get(x,y); }
void Get( int &a,int &b ) { a = x; b = y }
Point &operator=( const Point &pt ) { return *this = PointXY(pt); }
virtual PointXY &operator=( const PointXY &pt ) { pt.Get( x,y ); }
};

struct CursorPos : Point
{
CursorPos() { }
CursorPos( const Point &pt ) { int x,y; pt.Get(x,y);
::SetCursorPos(x,y); }
void Get( int &a,int &b ) { ::GetCursorPos( a,b ); }
Point &operator=( const Point &pt ) { return *this = CursorPos(pt); }
};


Cheers!

- Risto -
 
M

Michiel.Salters

Alex said:
Why do we need non-virtual destructor?
Because of vtable?

That's an implementation detail. The ISO standard reason is that any
virtual function destroys "POD-ness". That means that you cannot
memcpy a class if you have a virtual destructor, nor some other exotic
things that you probably don't want to do either.

(Implementations usually compile/run a bit smaller/faster, but this
rarely
matters. )

HTH,
Michiel Salters
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top