472,352 Members | 1,525 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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

How to set up virtual "get" methods?

Here is my situation

class base {
};

class child1 {
int data;
};

class child2 {
string data;
};

I want to access data from a base& object. Now, I know I can't do this
directly, but is there any way I could define a virtual "get" method
that could be called on a base& or base* object and return the correct
type?

I've tried declaring a get method in the base class and overriding it
in the child classes, but that gives an error as expected. I can't see
any way to use polymorphism because the return types must differ.

Jul 23 '05 #1
5 1815
This is a decision that needs to be made at compile time, otherwise how
would you know what type of variable to which assign the "get()". That
is, if get() returned both int and string you need to know at compile
time whether to do this

int x = object.get();

or

string x object.get();

Compile time stuff is done with templates, so there's probably a way to
do this with templates, but you need to ask yourself why you're needing
such a thing and decide whether or not it's good design.

Jul 23 '05 #2
[Grr... Google needs to make Groups work with the back button, at least
in Firefox. I hit a link by accident and lost most of this reply from
the first time I typed it. Anyway...]

The short answer is that you can't do it.

The medium answer is that you probably shouldn't do it. See BigBrian's
reply. If you post the context of what you're doing, we might be able
to help you come up with an alternate solution. (There are a couple
ideas below, after the long answer.) But you probably shouldn't have to
do this.

If you really want to do this, read on. There are a couple possible
solutions to do something sorta along the same lines as what you
want...

The long answer is that you can fake it. Make a union type, e.g.
typedef union { int number; string str; } string_or_int;
and return that. Depending on the type of variable you are storing the
result in, do like my_base_object.get_data().number or
my_base_object.get_data().str.

Actually, a better way is to make a discriminated union. It'll require
more typing because you'll have to define a class, but it's not too
hard. Add a union like above, then add another field that you can set
to indicate whether a number or string is stored in the union. Make a
get_integer() and a get_string() function that check this type before
returning, and throw an exception if the function call doesn't match
the type.

The longest answer is that an even better way is to drop the whole idea
in the first place. If you're going to go the route of the (possibly
discriminated) union, you might as well just put the two functions
right in the base class and do it that way. Something like this:
class base {
public:
virtual int get_child1_data() { throw someException("Class isn't a
child1"); }
virtual string get_child2_data() { throw someException("Class
isn't a child2"); }
}

class child1 {
...
public:
virtual int get_child1_data() { return data; }
}

(This is sorta hackish. There is probably a better way to do the same
idea. Actually, some might say the discriminated union idea is better.)

Another idea is if the string is going to be something like "123" you
could make the get function in child2 convert data to an integer and
return that; then the get function would be an int in each of its
occurances and it would all work out. Or, you could convert child1's
data to a string (so the integer 123 to the string "123") and return
that.
If this is still not flexible enough, perhaps you should consider
another language like Ruby where everything is a an object that derives
from one root and thus you don't have to worry about types in the same
sense as your typical imperative languages like C, C++, Java, C#, etc.,
only what operations (methods) the objects support. I think Smalltalk
would work too.

Jul 23 '05 #3
Basically what I'm doing is a simple interpreted programming language.
Because several of the operators work for different types, I wanted to
avoid the "obvious" solution with a discriminated union:

if (x.type == type1)
// Call operator for type1
else if (x.type == type2)
// Call operator for type2
else if (x.type == type 3)
// Call operator for type3
....

Polymorphism isn't the right solution as far as I can tell, and
templates are even messier than the long if..else or switch statements
after jumping through hoops to get them to work. I've looked into the
Boost library, but those are very general and complicated classes where
my need is minimal. Using Boost seems like it would be overkill, for
not really enough gain that I can see at present.

What I have works, but it's ugly and would be difficult to extend if I
added new operators or types.

Jul 23 '05 #4
Duck Dodgers wrote:
Basically what I'm doing is a simple interpreted programming language.
Because several of the operators work for different types, I wanted to
avoid the "obvious" solution with a discriminated union:

if (x.type == type1)
// Call operator for type1
else if (x.type == type2)
// Call operator for type2
else if (x.type == type 3)
// Call operator for type3
...

Polymorphism isn't the right solution as far as I can tell, and
templates are even messier than the long if..else or switch statements
after jumping through hoops to get them to work. I've looked into the
Boost library, but those are very general and complicated classes where
my need is minimal. Using Boost seems like it would be overkill, for
not really enough gain that I can see at present.

What I have works, but it's ugly and would be difficult to extend if I
added new operators or types.


Yep, been there, very ugly.

In my case, I want a generic "get_value" method that would return
the value of a {variant} field. The field could be integer, boolean,
string, etc. A record would be a collection of fields.

The solution for simple types is to return the value as a string.
Many types can be converted to an from strings.

Otherwise, you are looking at double dispatch and the Visitor
design pattern.

Most implementations of this dilemma use a generic pointer and
an enumerated value indicating the type of the data:
enum Variant_Type
{
Unknown, integer, string, etc
};

struct Variant
{
Variant_Type type;
void * pointer_to_data;
// or perhaps a union here
};

Probably the best route is the Visitor pattern.

--
Thomas Matthews
Jul 23 '05 #5
"Duck Dodgers" <mo*******@hotmail.com> wrote in message
class base {
};

class child1 {
int data;
};

class child2 {
string data;
};
I take it child1, child2 are supposed to derive from base.

Best way is to create an abstract base class Variable. From this derive
Integer and String. class base will have a virtual function that returns a
reference to a Variable.

Related to this will be double dispatch. You can look it up on the
internet.

Idea: If you have a function F1 that takes an Integer and an Integer,
create another function that takes a reference to two Variables and calls F1
after doing a static_cast to convert a reference to a Variable to a
reference to an Integer. If you have a function F2 that takes an Integer
and a String, create another function that again takes a reference to two
Variables and calls F2 after doing a static_cast. Store F1 and F2 in a map
along with the concatenation of typeid -- ie. the function related to F1 has
key strcat(typeid(Integer).name(), typeid(Integer).name()), and the function
related to F2 has key strcat(typeid(Integer).name(), typeid(String).name()).

Then create your generic function F that takes a reference to two Variables
and looks up the typeid in the map.
I want to access data from a base& object. Now, I know I can't do this
directly, but is there any way I could define a virtual "get" method
that could be called on a base& or base* object and return the correct
type?

I've tried declaring a get method in the base class and overriding it
in the child classes, but that gives an error as expected. I can't see
any way to use polymorphism because the return types must differ.


Jul 23 '05 #6

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

Similar topics

5
by: Chris Stromberger | last post by:
When issuing updates in mysql (in the console window), mysql will tell you if any rows matched and how many rows were updated (see below). I know...
16
by: Dave Opstad | last post by:
In this snippet: d = {'x': 1} value = d.get('x', bigscaryfunction()) the bigscaryfunction is always called, even though 'x' is a valid key....
12
by: Me | last post by:
Hi, I would like learn from people with experience in C++, which of the following styles of way to construct "get/set" member functions would be the...
5
by: kelvin | last post by:
How do I use get data in a url sent from aform on an other page. All i want to do is take this data and display it on the page. thanking you in...
6
by: Eitan | last post by:
Hello, I would like to know about the methods : post and get of ASP. What is the difference between them. Need some samples, and explanation,...
7
by: Javaman59 | last post by:
This is probably common knowledge to .Net gurus, but please bear with me while I share a discovery with the group... I needed to create a public...
2
by: martyn_wynne | last post by:
Hi, I have found a odd one, my submit button is not submitting on a method="get" form after using any form of DataBind? Has anyone struck this...
3
by: Bsr | last post by:
What is the difference between for the following methods. "GET", "HEAD", "PUT" or "POST". Ex:my $req =HTTP::Request->new(GET =>$url1); ...
3
by: =?Utf-8?B?cmFuZHkxMjAw?= | last post by:
The code below goes through all the methods in the given dll. I'm wondering how I can modify this to only get methods with a specific custom...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...
0
by: Matthew3360 | last post by:
Hi, I have been trying to connect to a local host using php curl. But I am finding it hard to do this. I am doing the curl get request from my web...
0
by: Carina712 | last post by:
Setting background colors for Excel documents can help to improve the visual appeal of the document and make it easier to read and understand....
0
BLUEPANDA
by: BLUEPANDA | last post by:
At BluePanda Dev, we're passionate about building high-quality software and sharing our knowledge with the community. That's why we've created a SaaS...
0
by: Rahul1995seven | last post by:
Introduction: In the realm of programming languages, Python has emerged as a powerhouse. With its simplicity, versatility, and robustness, Python...

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.