"alexhong2001" <al**********@hotmail.com> wrote in message
news:Wr********************@bgtnsc05-news.ops.worldnet.att.net...
When design a class, should always make it "derivable" as a base class? Is
there really a situation that the designed class not "derivable"?
When should make a member "protected"? Only when allowing the derived
class(es) directly access it?
Should destructor always be virtual?
Thanks for your comments!
Well, your questions cover a lot of territory. I would say that many classes
fall into two broad categories: concrete data types and abstract data types.
(Not everybody uses these names, btw.) Concrete data types have no virtual
methods and are not intended for use as base classes. They are tightly bound
to their implementations. Example: std::complex.
Not all destructors should be virtual. A concrete data type might have a
destructor (e.g. std::vector) but if so it will not be virtual. If you want
to reuse such a class, use encapsulation (aka composition) rather than
inheritance:
class Fred
{
private:
std::vector<double> m_whatever; // good way to reuse std::vector
...
};
NOT
class Fred : public std::vector<double> {...}; // bad way
Abstract data types are used when you have a set or polymorphic classes:
class IShape
{
public:
virtual void draw() const = 0;
virtual ~IShape() {}
};
The typical pattern is no data, no constructor, pure virtual methods, and a
do-nothing virtual destructor. Obviously, such a class is intended as a base
class:
class Circle : public IShape {...};
class Square : public IShape (...};
The point is that if I have an IShape pointer I can draw the shape without
knowing or caring what type it actually is.
There are many other basic designs but those are two I use a lot.
I don't use "protected" very often, but if I do it will contain a method
(not data) which is intended for use by derived classes. Putting data in a
protected area compromises encapsulation IMHO.
--
Cy
http://home.rochester.rr.com/cyhome/