473,326 Members | 2,134 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

derivable classes

mem
Concrete classes are ones that can be instantiated directly, as long as it
doesn't have pure virtual function.

However, people suggest that "Don't derive from concrete classes."

Does this mean that either make it abstract base class for it to be
derivable or keep them as "concrete" not to be derived at all? Then what's
the purpose of "concrete classes" of ordinary virtual function(s)?

Thanks!

Jul 22 '05 #1
11 1909
mem wrote:
Concrete classes are ones that can be instantiated directly, as long as it
doesn't have pure virtual function.

However, people suggest that "Don't derive from concrete classes."

Does this mean that either make it abstract base class for it to be
derivable or keep them as "concrete" not to be derived at all? Then what's
the purpose of "concrete classes" of ordinary virtual function(s)?


OO is not about classes and objects; it is about messages and methods.

The odds you will derive from a concrete class are low. But you must divorce
the idea of "a class without pure virtual functions" from that of a "class
that should be instantiated". Pragmatically, some classes that should be
instantiated will also be inherited.

Your design should duplicate no behavior. This means, in practice, that
interfaces tend to migrate up an inheritance graph, and implementation
migrates down, into non-pure functions. But the rule against duplication is
more important than the rule "Don't derive from concrete classes".

A related rule, "Don't derive unless you then override a method," is more
important. Read the /Effective C++/ books for a good explanation.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #2
class Rectangle
{

};
class Square : Rectangle
{
};

Above is an instance in which a Concrete Class has been inherited from.
There's nothing wrong with it because:

A) A Rectangle is a fully-fledged thing, you can describe one and talk about
it very specificly. You can simply have a rectangle, no frills.

B) A Square is a Rectangle.

The reason people may have come up with the rule "Don't inherit from a
concrete class", I shall explain as follows:
Class Vehicle
{
};
Class Car : public Vehicle
{
};

Let's assume that Vehicle is a concrete class, with no virtual functions,
pure or otherwise. Thus, it's a concrete class. Thus, you can create an
instance of it:

Vehicle FunkyVehicle;

And similarly you can create an object Car:

Car FunkyCar;
But what you'll see here is that a Vehicle is NOT a fully-fledged object!
Try describe a Vehicle. How does a Vehicle work? How many wheels does a
vehicle have? Does it run on petrol or deisel. You can't just simply have a
Vehicle! But you CAN just simply have a Rectangle.

In summation:

You're human, you have a brain - decide for yourself if what you're doing is
good and proper.

-JKop

Jul 22 '05 #3

"JKop" <NU**@NULL.NULL> wrote in message
news:C5******************@news.indigo.ie...
class Rectangle
{

};
class Square : Rectangle
{
};


B) A Square is a Rectangle.


Actually, this is one of the best examples of what is *not* a good example
for inheritance. :-)

In mathematical terms, sure, we all know that a square is a special case of
a rectangle, where all sides are of equal length. But that's simply adding
a *restriction* on the rectangle in order to define the square, not
providing a new version of the rectangle with special behavior or added
properties, which is what inheritance is more about.

To illustrate the problem, think about what a rectangle can have as
properties: length and width. And either of those can potentially be
changed, independently! It makes perfect sense for a rectangle to have
SetWidth() and SetHeight() functions to set those properties. But calling
such a function in the square class would be disastrous! Sure, you could
override those to set both width and height whenever either is called, but
that would be *really* confusing to someone using your objects, (especially
if using polymorphism through pointers to the base class).

I believe Meyers covers this exact case in one of his books.

Sorry if this muddles things for the OP, but I think we need to give a
better simple example of inheritance to newbies, something like "A
SalariedEmployee is an Employee".

-Howard

Jul 22 '05 #4

"mem" <me**@supnet.com> wrote in message
news:ZY*******************@bgtnsc04-news.ops.worldnet.att.net...
Concrete classes are ones that can be instantiated directly, as long as it
doesn't have pure virtual function.
That's redundant. If it has a pure virtual function, it's abstract, not
concrete.
However, people suggest that "Don't derive from concrete classes."

Does this mean that either make it abstract base class for it to be
derivable or keep them as "concrete" not to be derived at all? Then what's
the purpose of "concrete classes" of ordinary virtual function(s)?


Yes, I've heard that guideline and generally I don't follow it and I've
never run into problems. I think Meyers wrote about this in "Effective C++"
or "More Effective C++". I don't understand your last sentence. But I
think you can derive from concrete classes without running into trouble.
Jul 22 '05 #5

"mem" <me**@supnet.com> wrote in message
news:ZY*******************@bgtnsc04-news.ops.worldnet.att.net...
Concrete classes are ones that can be instantiated directly, as long as it
doesn't have pure virtual function.

However, people suggest that "Don't derive from concrete classes."

Does this mean that either make it abstract base class for it to be
derivable or keep them as "concrete" not to be derived at all? Then what's
the purpose of "concrete classes" of ordinary virtual function(s)?

Thanks!


I'm unsure what a "concrete" class is. Is it one that is "intended" to be
instantiated from?

If so, then in real life you are bound to have cases where a class that is
intended to be instantiated may also end up being inherited from.

In that case, you'll want to be sure to look at what functions you make
virtual, because someone deriving from you class will make decisions about
what to override based upon the default behavior, and if you later change
that default behavior, then they will need to revisit the idea of overriding
that behavior again.

This, I think, is the basic reason given to avoid deriving from such
classes, and to instead make an abstract class from which both you and
others can derive. That way, if you change your class' behavior, it won't
break theirs.

If by "concrete" you mean that no virtual functions exist at all, then that
class is not "intended" to be derived from, and obviously shouldn't be.
(But I doubt that's the meaning, since it's too obvious such a class is not
intended as a base class.)

-Howard

Jul 22 '05 #6

"Howard" <al*****@hotmail.com> wrote in message
news:8e*****************@bgtnsc05-news.ops.worldnet.att.net...

"mem" <me**@supnet.com> wrote in message
news:ZY*******************@bgtnsc04-news.ops.worldnet.att.net...
Concrete classes are ones that can be instantiated directly, as long as it doesn't have pure virtual function.

However, people suggest that "Don't derive from concrete classes."

Does this mean that either make it abstract base class for it to be
derivable or keep them as "concrete" not to be derived at all? Then what's the purpose of "concrete classes" of ordinary virtual function(s)?

Thanks!
I'm unsure what a "concrete" class is. Is it one that is "intended" to be
instantiated from?


Yes. It's a normal class.
If so, then in real life you are bound to have cases where a class that is
intended to be instantiated may also end up being inherited from.
This can only happen if a programmer makes it so. The suggestion that the
OP was asking about was that programmers do not make it so.
If by "concrete" you mean that no virtual functions exist at all,...
No.
then that
class is not "intended" to be derived from, and obviously shouldn't be.


No, that's not necessarily true (but it could be.) If a designer writes a
class with some functions that are not virtual, he might still intend for
that class to be derived from, but is saying those functions should not be
overridden.
Jul 22 '05 #7

"Howard" <al*****@hotmail.com> wrote in message
news:22*****************@bgtnsc05-news.ops.worldnet.att.net...

"JKop" <NU**@NULL.NULL> wrote in message
news:C5******************@news.indigo.ie...
class Rectangle
class Square : Rectangle

B) A Square is a Rectangle.
Actually, this is one of the best examples of what is *not* a good example
for inheritance. :-) In mathematical terms, sure, we all know that a

square is a special case ofa rectangle, where all sides are of equal length. But that's simply adding
a *restriction* on the rectangle in order to define the square, not
providing a new version of the rectangle with special behavior or added
properties, which is what inheritance is more about.


Howard, good point. However, this might make more sense

class Square
class Rectangle: public Square

A lot of this sort of thing is context dependent. It depends on which
constraints you are going to be modeling, and what you want your objects to
be able to do. If all you're going to do is ask things like area,
perimeter, and corner to corner distance, then this design works OK. The
invocation of the base class (Square) constructor from the Rectangle
constructor looks a little goofy, but it works. If different things are
important in your design, then this won't work. For example, if you're
writing polymorphic code to put square shapes into square holes, then a
rectangle isn't substitutable for a square.

But these design problems are nothing new. You always model what's
important. If you're modeling the animal world, and you get down to the
point in your hierarchy where you split egg layers from mammals, then what
do you do with a duck billed platypus? It depends on whether egg laying is
important to you, or if hair and warm-bloodedness are important to you.

class Square
{
public:
Square(int);
virtual int area();
private:
side;
};
class Rectangle
{
public:
Rectangle(int, int);
int area();
private:
side2;
};
Square::Square(int val) : side(val) {}
int Square::area()
{ return side*2; }

Rectangle::Rectangle(int val1, int val2) : Square(val1), side2(val2) {}
int Rectangle::area()
{ return side * side2; }
Jul 22 '05 #8

"jeffc" <no****@nowhere.com> wrote in message
news:40********@news1.prserv.net...
But these design problems are nothing new. You always model what's
important. If you're modeling the animal world, and you get down to the
point in your hierarchy where you split egg layers from mammals, then what
do you do with a duck billed platypus? It depends on whether egg laying is important to you, or if hair and warm-bloodedness are important to you.


By the way, this problem doesn't just exist for computer programmers. It
also exists for zoologists. They didn't know where to put the duck billed
platypus either. There are often no perfect solutions. They decided to put
it with the mammals. They decided that being hairy and warm-blooded in this
case were more important distinctions than laying eggs. But if they wanted
they could have created a completely different split off the hierarchy and
made a special case for this animal.
Jul 22 '05 #9
jeffc posted:
class Square
class Rectangle: public Square

Let's say I'm a painter and I paint portraits. I demand that all my
paintings be upon a square canvas. The customer supplies the canvas:
PaintPortrait(Square* Canvas);
But, if a Rectangle IS_A square, as you've specified, then the customer
could supply the painter with a rectangle:
int main(void)
{
Rectangle Canvas;

PaintPortrait(&Canvas);
}

Then again, you may simply just ignore the IS_A principle. It's your code
after all, and if it functions correctly, then it functions correctly.
-JKop
Jul 22 '05 #10

"JKop" <NU**@NULL.NULL> wrote in message
news:Pb******************@news.indigo.ie...
jeffc posted:
class Square
class Rectangle: public Square


Let's say I'm a painter and I paint portraits. I demand that all my
paintings be upon a square canvas. The customer supplies the canvas:

PaintPortrait(Square* Canvas);

But, if a Rectangle IS_A square, as you've specified, then the customer
could supply the painter with a rectangle:


At what point did you stop reading my post? Right before this?

"If different things are important in your design, then this won't work.
For example, if you're
writing polymorphic code to put square shapes into square holes, then a
rectangle isn't substitutable for a square."

You do understand you just described the exact situation I already
mentioned, right?
Jul 22 '05 #11
"Howard" <al*****@hotmail.com> wrote in message news:<22*****************@bgtnsc05-news.ops.worldnet.att.net>...
[snip example]
Actually, this is one of the best examples of what is *not* a good example
for inheritance. :-)
It's the classic "A's can X, B is an A, B can't X" trap.

All birds gotta fly,
Ostrich is a bird,
Ostrich can't fly.

All rectangles can have two different side lengths,
Square is a rectangle,
Square cannot have two different side lengths.
I believe Meyers covers this exact case in one of his books.


It's also covered fairly well in "C++ FAQs (2nd Edition)"
by Marshall P. Cline, Greg A. Lomow, and Mike Girou.

Basically, you have to give up one (or more)
of the three lines of the trap. And you detect the trap
in advance by insisting that derived classes can substitute
for the parent class. So, ask "Can I use a square every
time I need a rectangle?" If, in the context of the case,
the answer is no, then it is likely to be a bad choice for
public derivation.

Or, "Can I use an ostrich every time a bird is wanted?"
The context may say no, or it may say yes. For example,
when ostrich is required to fly, you could adjust things
so that somebody buys an airline ticket for the bird.
Or you could redefine "fly" in some other way such that
ostriches can fly. Or you could change the middle line,
such that "bird" and "ostrich" each derived from some
other entity, say "protoBird" that did not have any
characteristics about flying. Or you could relax the
requirement that birds must fly, say, by allowing the
call to "Fly" to throw an exception. In any case, you
have to drop one or more lines from the three of the trap.

But get the FAQ book as the coverage there is much better
than I've managed here.
Socks
Jul 22 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Bob Rock | last post by:
Hello, in the last few days I've made my first few attempts at creating mixed C++ managed-unmanaged assemblies and looking aftwerwards with ILDASM at what is visible in those assemblies from a...
9
by: Jack | last post by:
Hello I have a library of calculationally intensive classes that is used both by a GUI based authoring application and by a simpler non-interactive rendering application. Both of these...
2
by: Amit | last post by:
please see the following lines of codes : class ABase; // i want to make it non-derivable class Super { private: Super () {}; friend class ABase; };
2
by: joye | last post by:
Hello, My question is how to use C# to call the existing libraries containing unmanaged C++ classes directly, but not use C# or managed C++ wrappers unmanaged C++ classes? Does anyone know how...
18
by: Edward Diener | last post by:
Is the packing alignment of __nogc classes stored as part of the assembly ? I think it must as the compiler, when referencing the assembly, could not know how the original data is packed otherwise....
2
by: baba | last post by:
Hi all, I'm quite new to C#. I am trying to implement some basics reusable classes using this language and the .NET Framework technology. What I'm trying to do now is to implement a singleton...
6
by: ivan.leben | last post by:
I want to write a Mesh class using half-edges. This class uses three other classes: Vertex, HalfEdge and Face. These classes should be linked properly in the process of building up the mesh by...
0
by: ivan.leben | last post by:
I am writing this in a new thread to alert that I found a solution to the problem mentioned here: http://groups.google.com/group/comp.lang.c++/browse_thread/thread/7970afaa089fd5b8 and to avoid...
5
by: Amal P | last post by:
Dears, I have a question. class Data { }; class DisableDerive:virtual protected Data // A base class { private:
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.