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

Extending class to be a base class *properly*

Sorry if this has been discussed before (I'm almost certain it has), but
I didn't know what to google for.

My problem is, I have a class, a gtkmm widget, and I want it to serve as
a base class now, but I'm not sure if I'm taking the proper steps in
order to not break the whole class.

Are there any guidelines what I have to watch out for?

One question would e.g. be:
Some (or many) members which have been private so far, probably need to
be protected now. One problem is that I can't really tell in advance
which of those member should stay private and which ones should become
protected, because that mostly depends on what people intend to do with
their class when deriving from my widget.
But I suppose it's a bad idea to take this as an argument for making ALL
private members protected now?

Another question:
Is it sufficient to make the members in question protected, or should
they stay private and protected accessor methods introduced?

--
Matthias Kaeppler
Jul 23 '05 #1
1 1817
On Fri, 15 Apr 2005 19:49:51 +0200, Matthias Kaeppler
<no****@digitalraid.com> wrote:
Sorry if this has been discussed before (I'm almost certain it has), but
I didn't know what to google for.

My problem is, I have a class, a gtkmm widget, and I want it to serve as
a base class now, but I'm not sure if I'm taking the proper steps in
order to not break the whole class.

Are there any guidelines what I have to watch out for?
One of the few general principles I can think of is to make sure
objects have the appropriate polymorphic behavior. What happens if a
Descendant* is used as a Base*, or a Descendant& is used as a Base&?
Most everything else depends too much on the design specifics;
consequently, some of my suggestions below may not work for your case.
One question would e.g. be:
Some (or many) members which have been private so far, probably need to
be protected now. One problem is that I can't really tell in advance
which of those member should stay private and which ones should become
protected, because that mostly depends on what people intend to do with
their class when deriving from my widget.
But I suppose it's a bad idea to take this as an argument for making ALL
private members protected now?

C++ FAQ section 19, answers 7-9 deal with public/protected interfaces:
http://new-brunswick.net/workshop/c+....html#faq-19.7
Just remember that when the author talks about return on investment,
investment in the protected interface will reduce costs for
descendants associated with interface maintenance and upgrade.

What to make protected and what to make private is a difficult design
issue to fully address in the general case. My first bit of advice is
to transfer few private members to the protected interface at the
start. You can always add to the protected interface in later
versions.

Some of the same design considerations for public interfaces will
apply to protected interfaces. For instance, divorce implementation
from an object's more abstract properties as much as possible. You
won't get as much of a separation in the protected interface as in the
public, but you will get some. This can be as simple as typedef-ing
types for protected fields. The separation protects descendants from
changes in implementation. Another consideration is speed versus
stability. Private methods can be unstable in that they don't perform
many safety checks. Public methods should provide more in terms of
stability, perhaps at a speed cost. Protected methods could be
somewhere in between, checking subtle errors but leaving more obvious
ones to the developers of the descendants. Just don't forget to
document what future developers need to handle.

If you've got the time, another tool which sometimes applies is to
define invariants on the data stored in an object. All public
operations on the object must not invalidate the invariant. If a
private method breaks an invariant, don't make it protected. Similar
to what you later suggest, you can add protected methods which
accomplish the affects of particular sequences of private methods.
You can define relaxed versions of the public invariants for the
protected interface. Each protected method respects the protected
invariants, and particular sequences of protected methods will
preserve the public invariants. In the documentation for the
protected interface, require all public methods of descendants which
use a protected method must use it as part of such a sequence. This
isn't as safe as the public invariants, but is sometimes all you can
achieve.

Related to invariants are preconditions and postconditions,
specifically of the private methods. For safety's sake, sometimes
you'll want to create protected methods which check the preconditions
and then call a private method only if the check succeeds, or create
protected methods which clean-up after calling some private method.
Another question:
Is it sufficient to make the members in question protected, or should
they stay private and protected accessor methods introduced?


Creating protected accessors to private members is an intermediate
step (and a final one for some private fields). A more final solution
would be to define protected methods which "partially expose" the
private interface. These protected methods hide implementation
details, perform aggregates of the private operations (as when dealing
with invariants) and define operations on private fields (which may be
unneeded for the base's member functions).

For example, suppose a base class has a set of files. The set is
invisible publically, but it makes sense for subclasses to add to,
remove from or query what's in the set. The set is implemented as a
priority queue (and has no method corresponding to "member of"), but
this detail is to be hidden from subclasses. Thus the base is given
protected methods which treat the priority queue as a set. Not a
great example, as it makes sense for a priority queue to support the
interface of a set, but still illustrative.

Kanenas
Jul 23 '05 #2

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

Similar topics

4
by: henrikpierrou | last post by:
Hi, I am trying to extend an overridden base class method (printer) by printing some extra fields and then calling the base class method. Extract from the python tutorial: 'An overriding...
6
by: Fred | last post by:
Hi I have a class defined in a library that I'd like to add some extra functionality to. This will involve adding a few member variables and a few related methods. As I understand it I can...
5
by: Nick Flandry | last post by:
I'm running into an Invalid Cast Exception on an ASP.NET application that runs fine in my development environment (Win2K server running IIS 5) and a test environment (also Win2K server running IIS...
8
by: Mark Olbert | last post by:
I'm writing a custom MembershipProvider which uses a custom class derived from MembershipUser (basically, the derived class adds a field to the MembershipUser base class). When I try to configure...
4
by: Divick | last post by:
Hi all, I want to subclass std::exception so as to designate the type of error that I want to throw, out of my classes, and for that I need to store the messages inside the exception classes. I...
0
by: emin.shopper | last post by:
I had a need recently to check if my subclasses properly implemented the desired interface and wished that I could use something like an abstract base class in python. After reading up on metaclass...
3
by: katis | last post by:
Hi all :) Is it posible in xsd to change only minOccurs value of element in complex type by extending this type? The problem I'm trying to solve is this: I have two complex types -...
1
by: surf | last post by:
We have some open source tools that we use. I don't want to extend the classes in the tools source because the calls to new() happen in the tool source and we are supposed to avoid changing the...
0
by: Tom C | last post by:
In an N-tier app, what is the DOT NET approach for extending an application at all levels (i.e. DAL, Business Object, Client) for a customer or module specific deviation without changing the base...
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...
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...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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...

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.