interfacing the unlearned

C

chris

I have three derived classes that share one base class, we shall call them
Derived1, Derived2, and Derived 3. Each of the three derived class types
have simular methods. However the simlular methods were not canidates for
virtual functions, because the function arguments and return type differ for
each. I put the common methods and common data that does not differ in the
base class. We shall call it Base. All is well so far...

Now my boss wants me to make one class that is a collection of all three
derived types, we shall call this Collection. The interface to this
Collection must have an accessor that gives the user back a pointer to any
one of the forementioned derived types.

Now the problem is that he wants it so that it can be any of the 3!
The only mechanism I can think to accomplish this, is dynamic casting. I
think this is exactly what dyanmic cast is for.

I say ok, we can return the base, but they will have to dyanmically cast it
to whichever of the three types it was originally. If the user does not
'remember' what type it was before inserting it to the collection, this
requires the user to:

Derived1 * isDerived1;
Derived2 * isDerived2;
Derived3 * isDerived3;

isDerived1 = dynamic_cast<Derived1 *>(returned_base_pointer)
if(isDerived1)
// it was a Derived1 type
isDerived2 = dynamic_cast<Derived2 *>(returned_base_pointer)
if(isDerived2)
// it was a Derived2 type
..
..
etc.

Problem is that he thinks, and I agree, that 70% or more of programmers do
not know how to use a dynamic_cast. At my last job, no one in the building
knew what they were looking at. The main goal of the entire interface is
ease of use, so...I am not allowed to force the user to use a dynamic_cast.
Well, this is really becoming a problem, because I don't think it is
possible at all to contain any of the three derived types without it, but
rather only one.

Of course I can dynamic_cast internally...

// returns one of the three pointers, and the others are NULL
GetElement(ID, Derived1 *, Derived2 *, Derived3 *) ;

but isn't that sillyness? Is it really our problem if the user does not know
how to dynamic cast themselves? If I had my way, everyone would know and use
C++, never mix C and C++, and I would never have to account for a user of an
interface not knowing how to accomplish a task, but unfortuantly that is
very far from the truth.

I could document how to use dynamic cast along with the method, but then
isn't my documentation insulting to others?

Has anyone run across a simular situation?
I've only been programming on the job for less than a year. I am not sure
what to do or say here!
 
J

Jim Langston

chris said:
I have three derived classes that share one base class, we shall call them
Derived1, Derived2, and Derived 3. Each of the three derived class types
have simular methods. However the simlular methods were not canidates for
virtual functions, because the function arguments and return type differ
for each. I put the common methods and common data that does not differ in
the base class. We shall call it Base. All is well so far...

Now my boss wants me to make one class that is a collection of all three
derived types, we shall call this Collection. The interface to this
Collection must have an accessor that gives the user back a pointer to any
one of the forementioned derived types.

Now the problem is that he wants it so that it can be any of the 3!
The only mechanism I can think to accomplish this, is dynamic casting. I
think this is exactly what dyanmic cast is for.

I say ok, we can return the base, but they will have to dyanmically cast
it to whichever of the three types it was originally. If the user does not
'remember' what type it was before inserting it to the collection, this
requires the user to:

Derived1 * isDerived1;
Derived2 * isDerived2;
Derived3 * isDerived3;

isDerived1 = dynamic_cast<Derived1 *>(returned_base_pointer)
if(isDerived1)
// it was a Derived1 type
isDerived2 = dynamic_cast<Derived2 *>(returned_base_pointer)
if(isDerived2)
// it was a Derived2 type
.
.
etc.

Problem is that he thinks, and I agree, that 70% or more of programmers do
not know how to use a dynamic_cast. At my last job, no one in the building
knew what they were looking at. The main goal of the entire interface is
ease of use, so...I am not allowed to force the user to use a
dynamic_cast. Well, this is really becoming a problem, because I don't
think it is possible at all to contain any of the three derived types
without it, but rather only one.

Of course I can dynamic_cast internally...

// returns one of the three pointers, and the others are NULL
GetElement(ID, Derived1 *, Derived2 *, Derived3 *) ;

but isn't that sillyness? Is it really our problem if the user does not
know how to dynamic cast themselves? If I had my way, everyone would know
and use C++, never mix C and C++, and I would never have to account for a
user of an interface not knowing how to accomplish a task, but
unfortuantly that is very far from the truth.

I could document how to use dynamic cast along with the method, but then
isn't my documentation insulting to others?

Has anyone run across a simular situation?
I've only been programming on the job for less than a year. I am not sure
what to do or say here!

If it is ease of use you are going for, why not just make the functions
virtual anyway? You say the user has to pass different number of parameters
to the class if it's a different sub class so the user has to know what type
of class it is anyway. So go ahead and make them virtual.

virtual void Fucntion( int ) {};
virtual void Function( char* ) {};
virtual void Function( int, char* ) {};

The only problem you'll come into is if the same function name can return
different types. I.E.

virtual int Function( int ) = 0;
virtual char* Function( int ) = 0;

isnt't going to work. In that case I would give the functions different
names.

I know it's a pain for you to have to make all the virutal functions, but as
it is, you are doing this so other programs can use your class easier.
 
T

Tim H

Now my boss wants me to make one class that is a collection of all three
derived types, we shall call this Collection. The interface to this
Collection must have an accessor that gives the user back a pointer to any
one of the forementioned derived types.

Now the problem is that he wants it so that it can be any of the 3!
The only mechanism I can think to accomplish this, is dynamic casting. I
think this is exactly what dyanmic cast is for.

When you have to bust out the dynamic cast, you should start to ask if
you have a design problem.
I have invented this same situation myself, and I consider it to be a
design problem for which there is no good answer.
I say ok, we can return the base, but they will have to dyanmically cast it
to whichever of the three types it was originally. If the user does not
'remember' what type it was before inserting it to the collection, this
requires the user to:

If the user does not remember the type, then they need to use typeid()
or you need to keep an "enum type" in the base class.
 
P

pawel.kunio

I have three derived classes that share one base class, we shall call them
Derived1, Derived2, and Derived 3. Each of the three derived class types
have simular methods. However the simlular methods were not canidates for
virtual functions, because the function arguments and return type differ for
each. I put the common methods and common data that does not differ in the
base class. We shall call it Base. All is well so far...

Now my boss wants me to make one class that is a collection of all three
derived types, we shall call this Collection. The interface to this
Collection must have an accessor that gives the user back a pointer to any
one of the forementioned derived types.

Now the problem is that he wants it so that it can be any of the 3!
The only mechanism I can think to accomplish this, is dynamic casting. I
think this is exactly what dyanmic cast is for.

I say ok, we can return the base, but they will have to dyanmically cast it
to whichever of the three types it was originally. If the user does not
'remember' what type it was before inserting it to the collection, this
requires the user to:

Derived1 * isDerived1;
Derived2 * isDerived2;
Derived3 * isDerived3;

isDerived1 = dynamic_cast<Derived1 *>(returned_base_pointer)
if(isDerived1)
// it was a Derived1 type
isDerived2 = dynamic_cast<Derived2 *>(returned_base_pointer)
if(isDerived2)
// it was a Derived2 type
.
.
etc.

Problem is that he thinks, and I agree, that 70% or more of programmers do
not know how to use a dynamic_cast. At my last job, no one in the building
knew what they were looking at. The main goal of the entire interface is
ease of use, so...I am not allowed to force the user to use a dynamic_cast.
Well, this is really becoming a problem, because I don't think it is
possible at all to contain any of the three derived types without it, but
rather only one.

Of course I can dynamic_cast internally...

// returns one of the three pointers, and the others are NULL
GetElement(ID, Derived1 *, Derived2 *, Derived3 *) ;

but isn't that sillyness? Is it really our problem if the user does not know
how to dynamic cast themselves? If I had my way, everyone would know and use
C++, never mix C and C++, and I would never have to account for a user of an
interface not knowing how to accomplish a task, but unfortuantly that is
very far from the truth.

I could document how to use dynamic cast along with the method, but then
isn't my documentation insulting to others?

Has anyone run across a simular situation?
I've only been programming on the job for less than a year. I am not sure
what to do or say here!

i would try adding to the base:

template<class T>
bool check_castable(Base*p)
{
return dynamic_cast<T*>(p) != 0;
}
 

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,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top