473,388 Members | 1,346 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,388 software developers and data experts.

Questions of designing a class

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!
Jul 22 '05 #1
3 1313
"alexhong2001" <al**********@hotmail.com> wrote
When design a class, should always make it "derivable" as a base class?
No. Derivation is something you need to plan and it has non-trivial efficiency
costs.
Is there really a situation that the designed class not "derivable"?
It's not a question of being "derivable", but rather of whether it makes sense
to derive from it, and in many cases, it doesn't. For example, no one but a rank
beginner would derive from std::string or std::vector. The derived class
couldn't be used polymorphically and would almost certainly violate the Liskov
Substitutability Principle.
When should make a member "protected"?
I hate generalizations, but in this case, "rarely" is a good answer (and
arguably, "never" might be a better one). Protected members make it difficult to
modify a base class because the derived classes come to depend on its internals.
If you absolutely insist on having protected members, I'd STRONGLY urge you to
make them protected methods and not protected data members.
Should destructor always be virtual?


No, for the same reasons as outlined in the first answer.

Claudio Puviani
Jul 22 '05 #2
alexhong2001 wrote:
When design a class, should always make it "derivable" as a base class?
You might think you can never ever change a class once written. People who
think that tend to make too many things virtual.

If you write lots of tests at the same time as you code, you become free to
implement only the simplest design that passes the tests. But if you then
add more tests requesting more features, you can then add code that passes
the tests, and refactor that code into a new, clean design.

Following this technique keeps you out of the debugger, and prevents you
from over-designing classes. You will make classes that contain behavior -
not specifically classes designed to be base classes. But when the time
comes to merge interfaces into a base class, after the change you can test
to ensure changing didn't add a bug.

Read /Design Patterns/ to see popular ways to put objects together into
object models.
Is
there really a situation that the designed class not "derivable"?
std::string is not derivable - it has no virtual methods, so there's no
reason to inherit it. Sometimes people inherit it to form a "convenience
class" that changes its interface a little.

But if we controlled the source to a class we would make it derivable when
we find a reason to.
When should make a member "protected"? Only when allowing the derived
class(es) directly access it?
I never saw a reason for "protected" but there might be one out there.
Disregard it.
Should destructor always be virtual?


Yes. This is a different topic - a Sane Subset. That means you don't write
every possible combination of C++ statements, you only use specific
combinations known to work, and you prefer them to all others. (Read
/Effective C++/ and /Exceptional C++/ to learn what a thin line C++ can
place between bad design and sanity!)

Always use references without a reason to use pointers. Always use local
storage without a reason to use heap storage, etc.

C++ permits bugs in certain situations with non-virtual destructors because
they also optimize certain other situations. So, treat a non-virtual
destructor as the exceptional case, when you need speed, and use virtual
destructors in all other situations.

--
Phlip
http://www.xpsd.org/cgi-bin/wiki?Tes...UserInterfaces
Jul 22 '05 #3
"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/
Jul 22 '05 #4

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

Similar topics

5
by: Laser Lu | last post by:
Can we define events in a class when coding using VBScript in ASP? I still have the second question, even if the answer is positive. That is whether the two standard events of a calss module in VB,...
1
by: Naren | last post by:
Hello All, I am presently designing a cleint server architecture. I require some suggestions and help by the experts here. MyServer class conatins a list of Mysock class. class Myserver {...
2
by: xuatla | last post by:
Hi, I am not sure whether I describe the subject correctly. What I want to do is for a matrix class --------------------------- class CMatrix { private:
6
by: Gary James | last post by:
This may not be a direct C# question, but since I'll be using using C# for development, I thought I'd pose the question here. I'll soon be involved in the design of a new software product that...
2
by: Sky Sigal | last post by:
Hello: I'm currently messing around, and need as much feedback/help as I can get, trying to find the most economical/graceful way to build usercontrols that rely on styling to look any good... ...
2
by: mac_ferrari1975 | last post by:
Hi all, Consider the situation. I am designing class library and I have a class A. I derived class B and class C from A but derivation is not virtual. for exa. class A {}; class B : public A...
8
by: NH | last post by:
Hi, I'm looking for some opinions and advice on designing ASP.Net apps. Let me explain my approach to how I currently design and hopefully you can give me some advice. I create systems for a...
6
by: S. Lorétan | last post by:
Hi guys. I am preparing the rewriting of an huge existing application in VB6. This software is a mess of 10 years of patchs and new functionalities added randomly, and didn't have any logical or...
1
by: asdf | last post by:
Class Aclass{ int x; public: Aclass():x(0){}; }; Aclass B; Because B is an object of the class Aclass, and x is the private data member, so, B cannot access
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.