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

Pass a derived object to func so that it is base?

Is there a way to pass a derived object so that the called function thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

class ConvexHull : public Hull
{
// ....
int DoIt() { TRACE("ConvexHull"); }
// ....
}

class Fitted
{
// ....
int FitHull(Hull *in_phull) { in_phull->DoIt(); }
// ....
}

main()
{
Fitted fittedData;
ConvexHull chull;
Hull *phull=&chull;

fittedData.FitHull(&chull);

fittedData.FitHull(phull);
}

Output is:
ConvexHull
ConvexHull

Is there a way to pass phull so that it forgets about its derived class? I
want the output to be:

ConvexHull
Hull

Thanks.
Jan 10 '06 #1
8 1826
Tom Wilson wrote:
Is there a way to pass a derived object so that the called function thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

class ConvexHull : public Hull
{
// ....
int DoIt() { TRACE("ConvexHull"); }
// ....
}

class Fitted
{
// ....
int FitHull(Hull *in_phull) { in_phull->DoIt(); }
// ....
}

main()
{
Fitted fittedData;
ConvexHull chull;
Hull *phull=&chull;

fittedData.FitHull(&chull);

fittedData.FitHull(phull);
}

Output is:
ConvexHull
ConvexHull

Is there a way to pass phull so that it forgets about its derived class? I
want the output to be:

ConvexHull
Hull


Sounds like you want a cast. Often (although not always), the need for
a cast - except in very low-level code - is evidence of a design flaw.
In addition, it sounds like you want intentional slicing, which in many
cases suggests a design flaw.

Still, if you're determined to do this, you could always do:

Hull hull = chull; // intentional slicing of object
fittedData.FitHull(&hull); // pass the sliced object

Frankly, it pains me even to suggest this...

Best regards,

Tom

Jan 10 '06 #2

Tom Wilson wrote:
Is there a way to pass a derived object so that the called function thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

[...]


Maybe I miss the point, but if you would not declare DoIt() to be
virtual, then you would get your intended behaviour, right?
(Why overwrite this method at all, if it should do the same things for
all classes?)

Regards,
Matthias

Jan 10 '06 #3
On Mon, 9 Jan 2006 16:39:13 -0800, "Tom Wilson"
<tw*****@atmos.washington.edu> wrote:
Is there a way to pass a derived object so that the called function thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

class ConvexHull : public Hull
{
// ....
int DoIt() { TRACE("ConvexHull"); }
// ....
}

class Fitted
{
// ....
int FitHull(Hull *in_phull) { in_phull->DoIt(); }
// ....
}

main()
{
This must be:
int main()

Otherwise, the behavior is undefined in C++.
Fitted fittedData;
ConvexHull chull;
Hull *phull=&chull;

fittedData.FitHull(&chull);

fittedData.FitHull(phull);
}

Output is:
ConvexHull
ConvexHull

Is there a way to pass phull so that it forgets about its derived class? I
want the output to be:

ConvexHull
Hull

Thanks.


What the others have said. But you could make Hull an abstract class
and only implement the function in derived classes. Then it would call
whatever version of FitHull() is appropriate for that class.

Rather than making Hull::DoIt() non-virtual, if you don't want an
abstract class, I would provide a separate function for calling the
base class function.

As someone else said, you could use a cast. That would look like this:

class Fitted
{
// ....
int FitHull(Hull *in_phull) {
ConvexHull * cvh = dynamic_cast<ConvexHull*>(in_phull);
if (cvh)
in_phull->DoIt();
else
in_phull->Hull::DoIt();
}
// ....
}

For each derived type, you'd need another if..else branch with the
appropriate cast. That's abusing polymorphism, though ... you REALLY
don't want to do that, do you?

--
Bob Hairgrove
No**********@Home.com
Jan 10 '06 #4
"Thomas Tutone" <Th***********@yahoo.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Tom Wilson wrote:
Is there a way to pass a derived object so that the called function
thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

class ConvexHull : public Hull
{
// ....
int DoIt() { TRACE("ConvexHull"); }
// ....
}

class Fitted
{
// ....
int FitHull(Hull *in_phull) { in_phull->DoIt(); }
// ....
}

main()
{
Fitted fittedData;
ConvexHull chull;
Hull *phull=&chull;

fittedData.FitHull(&chull);

fittedData.FitHull(phull);
}

Output is:
ConvexHull
ConvexHull

Is there a way to pass phull so that it forgets about its derived class?
I
want the output to be:

ConvexHull
Hull
Sounds like you want a cast. Often (although not always), the need for
a cast - except in very low-level code - is evidence of a design flaw.
In addition, it sounds like you want intentional slicing, which in many
cases suggests a design flaw.

Still, if you're determined to do this, you could always do:

Hull hull = chull; // intentional slicing of object
fittedData.FitHull(&hull); // pass the sliced object

Frankly, it pains me even to suggest this...


Yes, this would be bad. Let's say for instance, my Hull class has 500,000
points that define the Hull. ConvexHull contains pointers to those points
that define only the ConvexHull. Speed is important. We have a lot of
hulls and a lot of points. I don't want to be creating a copy of this base
set of points.... Sometimes I want to work with the points that define the
entire Hull (perimeter) and sometimes I want to work with all the points. I
was hoping to have member functions of class Fitted be able to handle a Hull
object or a ConvexHull object and call FitHull() on the appropriate set of
points depending on the type of object passed in.
For example,

void Fitted::FitHull(Hull *in_phull)
{
//...
// in_phull might be a Hull, might be a ConvexHull.....
//
double pd = in_phull->GetPt(i);
}


Best regards,

Tom

Jan 10 '06 #5
The method does not do the same thing for both classes. DoIt() outputs
"Hull" in the base class and "ConvexHull" in the ConvexHull class.

Additional discussion is in response to Tommy Tutone message.
"Matthias" <ne**@ingbh.de> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...

Tom Wilson wrote:
Is there a way to pass a derived object so that the called function
thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

[...]


Maybe I miss the point, but if you would not declare DoIt() to be
virtual, then you would get your intended behaviour, right?
(Why overwrite this method at all, if it should do the same things for
all classes?)

Regards,
Matthias

Jan 10 '06 #6
Thanks Bob for your help.
Unfortunately, in the real world there is code that you don't have months or
even a week to rewrite that you come across that almost does what you want
it to do, but not quite. Rewriting/redesigning would be great if I had a
sugar momma and didn't work for the man.

Anyway, it was just a C++ logistics question, seeing what people had to say
about it. I guess I left a little detail out for the option of redesigning
the code....the key constraint I didn't mention is I can't be making copies
of this object willy nilly (which your suggestion doesn't do, so that was
good).

So your code in FitHull is terrible, but it fits the bill. Just what I was
looking for... An answer to the question.

class Hull has about 500,000 points so I don't want to be making copies of
objects. The convexHull points are just a subset of the Hull points, though
it could be a fairly large subset. So, theoretically, I would probably put
the Hull data in its own class and create 2 new classes the perform
operations on the Hull data object.

Thanks again.


"Bob Hairgrove" <in*****@bigfoot.com> wrote in message
news:u4********************************@4ax.com...
On Mon, 9 Jan 2006 16:39:13 -0800, "Tom Wilson"
<tw*****@atmos.washington.edu> wrote:
Is there a way to pass a derived object so that the called function thinks
it is the base class?

Here's the lowdown.

class Hull
{
// ....
virtual int DoIt() { TRACE("Hull"); }
// ....
}

class ConvexHull : public Hull
{
// ....
int DoIt() { TRACE("ConvexHull"); }
// ....
}

class Fitted
{
// ....
int FitHull(Hull *in_phull) { in_phull->DoIt(); }
// ....
}

main()
{


This must be:
int main()

Otherwise, the behavior is undefined in C++.
Fitted fittedData;
ConvexHull chull;
Hull *phull=&chull;

fittedData.FitHull(&chull);

fittedData.FitHull(phull);
}

Output is:
ConvexHull
ConvexHull

Is there a way to pass phull so that it forgets about its derived class?
I
want the output to be:

ConvexHull
Hull

Thanks.


What the others have said. But you could make Hull an abstract class
and only implement the function in derived classes. Then it would call
whatever version of FitHull() is appropriate for that class.

Rather than making Hull::DoIt() non-virtual, if you don't want an
abstract class, I would provide a separate function for calling the
base class function.

As someone else said, you could use a cast. That would look like this:

class Fitted
{
// ....
int FitHull(Hull *in_phull) {
ConvexHull * cvh = dynamic_cast<ConvexHull*>(in_phull);
if (cvh)
in_phull->DoIt();
else
in_phull->Hull::DoIt();
}
// ....
}

For each derived type, you'd need another if..else branch with the
appropriate cast. That's abusing polymorphism, though ... you REALLY
don't want to do that, do you?

--
Bob Hairgrove
No**********@Home.com

Jan 10 '06 #7
Tom Wilson wrote:
Let's say for instance, my Hull class has 500,000
points that define the Hull. ConvexHull contains pointers to those points
that define only the ConvexHull. Speed is important. We have a lot of
hulls and a lot of points. I don't want to be creating a copy of this base
set of points.... Sometimes I want to work with the points that define the
entire Hull (perimeter) and sometimes I want to work with all the points. I
was hoping to have member functions of class Fitted be able to handle a Hull
object or a ConvexHull object and call FitHull() on the appropriate set of
points depending on the type of object passed in.


If you have some notion of an "appropriate set of points" which differs
between
Hull and ConvexHull, then why isn't there a GetAppropriateSetOfPoints?
Then every other caller that doesn't care about ConvexHull's or
AlmostConvexHull's or CatamaranHull's or ... can simply call that
function.

HTH,
Michiel Salters

Jan 10 '06 #8
On Tue, 10 Jan 2006 09:20:31 -0800, "Tom Wilson"
<tw*****@atmos.washington.edu> wrote:
Thanks Bob for your help.
Unfortunately, in the real world there is code that you don't have months or
even a week to rewrite that you come across that almost does what you want
it to do, but not quite. Rewriting/redesigning would be great if I had a
sugar momma and didn't work for the man.
I've been there before, too .. not a pleasant situation to be in!
Maybe after the deadline there will be a little time to go over the
design again (hopefully).
Anyway, it was just a C++ logistics question, seeing what people had to say
about it. I guess I left a little detail out for the option of redesigning
the code....the key constraint I didn't mention is I can't be making copies
of this object willy nilly (which your suggestion doesn't do, so that was
good).

So your code in FitHull is terrible, but it fits the bill. Just what I was
looking for... An answer to the question.

class Hull has about 500,000 points so I don't want to be making copies of
objects. The convexHull points are just a subset of the Hull points, though
it could be a fairly large subset. So, theoretically, I would probably put
the Hull data in its own class and create 2 new classes the perform
operations on the Hull data object.


Good luck!

--
Bob Hairgrove
No**********@Home.com
Jan 10 '06 #9

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

Similar topics

7
by: Christian Engström | last post by:
When i compile the program listed below with gcc version 3.3.1 (MinGW on Windows XP) I get the following result: Calling 'func(d)': 'base' copy constructor Calling 'func(*d_handle)': 'base'...
1
by: FP | last post by:
I have a function that returns a base class pointer as in: baseClass<T>* FunctionA( ); As you can see the baseClass is templated. FunctionA is found in a third templated class. What I'm...
10
by: nospam | last post by:
Hello! I can pass a "pointer to a double" to a function that accepts double*, like this: int func(double* var) { *var=1.0; ... }
3
by: Brad Navarro | last post by:
OK, I may be asking for the impossible, but I'll give it a shot: For a case like this: using System.Data.SqlClient; abstract class Base { private SqlConnection DBConnect; Base(string...
6
by: Taran | last post by:
Hi All, I tried something with the C++ I know and some things just seem strange. consider: #include <iostream> using namespace std;
2
by: Kevin Frey | last post by:
In a derived class I am trying to redefine the implementation of a interface method defined in a base class - the base class interface method was not declared virtual. I have yet to actually...
18
by: happyvalley | last post by:
Hi, basically, the test function get a char pointer, and assigned a string to it. then the string is passed back by the call-by-reference mechanism. in test(), I reallocate some memory for the...
12
by: raylopez99 | last post by:
Keywords: scope resolution, passing classes between parent and child forms, parameter constructor method, normal constructor, default constructor, forward reference, sharing classes between forms....
3
by: Pranav | last post by:
include <iostream> #include <unistd.h> #include <stdlib.h> class base{ public : virtual void disp(){ std::cout << "Base Class\n";} void show(){ std::cout << "Base Show\n"; } };
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?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.