LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-14-2007, 04:17 AM   #1
Ephracis
Senior Member
 
Registered: Sep 2004
Location: Sweden
Distribution: Ubuntu, Debian
Posts: 1,109

Rep: Reputation: 49
Two return types


Hi,

Simple question: if I have a method in a class which will return either type A or type B, how should I do?

I have a list of objects, the objects can be of two types. So when I call at(int) it can return either a pointer to object of type A or a pointer to an object of type B.

EDIT:
To extend it a little bit, is there a way of managing a Vector containing two types? Not a map, but a sort of Vector<typeA or typeB>.

Regards,

Last edited by Ephracis; 01-14-2007 at 04:48 AM.
 
Old 01-14-2007, 05:00 AM   #2
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
There are a couple of approaches to this, the ones I am thinking about could use the following
Boost Any or Boost Variant, yet these would require you to know the type or a way of finding the type. So you could therefore using std::vector<void*> (which is what boost uses for pointer vectors) and cast to the correct type, but I feel this defeats your purpose.

Last edited by dmail; 01-14-2007 at 05:03 AM.
 
Old 01-14-2007, 07:36 AM   #3
traene
Member
 
Registered: Jan 2005
Distribution: Archlinux, Debian, grml
Posts: 210

Rep: Reputation: 33
Java for instance has the everything is an object aproach. You just return an java.lang.Object
from your method. Maybe these objects have something in common, some common interface or something,
so you can return an (abstract) base type.
 
Old 01-14-2007, 07:55 AM   #4
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Originally Posted by traene
Java for instance has the everything is an object aproach. You just return an java.lang.Object
from your method. Maybe these objects have something in common, some common interface or something,
so you can return an (abstract) base type.
This is how the inner workings of boost Any work, yet the types contained with in the "Any" class need not have any relation to each other.
 
Old 01-14-2007, 09:14 AM   #5
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 40
Quote:
Originally Posted by Ephracis
I have a list of objects, the objects can be of two types. So when I call at(int) it can return either a pointer to object of type A or a pointer to an object of type B.

To extend it a little bit, is there a way of managing a Vector containing two types? Not a map, but a sort of Vector<typeA or typeB>.
What language are you using? I'm guessing from your description that it's something like C++ or Java. The cleanest way would be to create an abstract class that both typeA and typeB implement. Then your vector would contain instances of that abstract class. Alternatively, in C++ you could use unions to express multiple possible types as a single one. This isn't nearly as clean or safe in C++ as in languages like Ada or OCaml, but it is possible.
 
Old 01-14-2007, 09:39 AM   #6
Libra
LQ Newbie
 
Registered: Jan 2007
Location: Austria
Distribution: Ubuntu 8.04 Hardy Heron LTS
Posts: 10

Rep: Reputation: 0
if it's C++, I would do it like this:

Code:
enum {tpA, tpB} retType_t;


void *at(int i, retType_t *tp)
{
  void *fnc;
  ...
  if (...)
  {
    *tp = tpA;
    fnc = A;
  }
  else
  {
    *tp = tpB;
    fnc = B;
  }
  return fnc;
}
In this case, the caller knows by the value tp is set to to what class it has to be casted.
 
Old 01-14-2007, 10:02 AM   #7
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
In some situations you could use this, but if the class is in a hierarchy of classes then you could get splicing of data. Ephracis post some more information, it may be a idea to use a design pattern like visitor and thus let the caller call the correct method and get the correct type.

Last edited by dmail; 01-14-2007 at 10:03 AM.
 
Old 01-14-2007, 10:12 AM   #8
Ephracis
Senior Member
 
Registered: Sep 2004
Location: Sweden
Distribution: Ubuntu, Debian
Posts: 1,109

Original Poster
Rep: Reputation: 49
I am using C++ and here is how it looks:

I have a DataList which contains a vector of DataGroups and DataItems.
I have a DataGroup which contains a vector of DataGroups and DataItems.
I have a DataItem class.

Look at it as item is a file, group is a directory and list is root.

DataGroup and DataItem both inherits from DataAbstract, but they add a lot of functionality to it.

My object will create a DataList instance and add some groups and items, and within the groups there will be more nested groups and at last the items.. Just like a file tree or something like that, groups in groups, items in groups and everything in one list.

Then, another class will get this DataList and go through it and take different actions if the item is of type DataGroup or DataItem. I am not writing this class, I just export a pointer to my class DataList which this class will then use.

I need a way of just containing and structuring these classes in a simple way and I want DataList and DataGroup to be able to do stuff like add(DataGroup), add(DataItem) and at(int position).
 
Old 01-14-2007, 10:52 AM   #9
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
Just like a file tree
It sounds very much like a tree, where a item is a node, list and group are trees.
This may sound condescending have you tried to think and design it like this.

Last edited by dmail; 01-14-2007 at 10:57 AM.
 
Old 01-14-2007, 04:00 PM   #10
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 40
What's the difference between DataGroup and DataList? Except for the fact that a DataList is expected by the other function.

You can use DataAbstract to store both types into the same vector, like this:
Code:
#include <iostream>
#include <string>
#include <vector>

class DataAbstract {
public:
    virtual std::string get() = 0;
};

class DataGroup : public DataAbstract {
public:
    std::string get() {
        return "I'm a DataGroup.";
    }
};

class DataItem : public DataAbstract {
public:
    std::string get() {
        return "I'm a DataItem.";
    }
};

int main(int argc, char** argv) {
    std::vector<DataAbstract*>* v = new std::vector<DataAbstract*>();
    v->push_back(new DataGroup());
    v->push_back(new DataItem());
    std::cout << "Item 0 says \"" << v->at(0)->get() << "\"\n";
    std::cout << "Item 1 says \"" << v->at(1)->get() << "\"\n";
    if (typeid(*(v->at(0))) == typeid(*(v->at(1)))) {
        std::cout << "They're the same type!\n";
        std::cout << "Both are type " << typeid(*(v->at(0))).name() << ".\n";
    }
    else {
        std::cout << "They're different types!\n";
        std::cout << "Item 0 is of type " << typeid(*(v->at(0))).name() << ".\n";
        std::cout << "Item 1 is of type " << typeid(*(v->at(1))).name() << ".\n";
    }
    return 0;
}
At the end there you can see how to check the dynamic type of the contents of the vector. Note that the name() of a type is implementation defined: with GCC 3.4.3 for example, I see "9DataGroup" and "8DataItem".
 
Old 01-15-2007, 04:44 AM   #11
Libra
LQ Newbie
 
Registered: Jan 2007
Location: Austria
Distribution: Ubuntu 8.04 Hardy Heron LTS
Posts: 10

Rep: Reputation: 0
If I have more time, I will search more of that. Since I am an old Pascal programmer, I know the concept of "Class Pointers", of which I have noticed that there is an equivalent in C++, too. Since you have identical parent classes, this will work. In Delphi, you have to define

Type TMyClassPointer = class of TMyParentClass;

May be this helps you so far that you can google around it for C++.
 
Old 01-15-2007, 11:57 PM   #12
Ephracis
Senior Member
 
Registered: Sep 2004
Location: Sweden
Distribution: Ubuntu, Debian
Posts: 1,109

Original Poster
Rep: Reputation: 49
There isn't much difference between DataList and DataGroup right now, but the thing is that DataList is what the other classes will see and use, and it will act as root.

I was thinking of using QStack to store the items and groups but I need a way of reordering all items and also get the index where an item is located, this seems a little bit complicated with a QStack.
 
Old 01-16-2007, 06:23 AM   #13
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 40
Unless I misunderstand your problem, just make DataList a vector of DataAbstract, then add < and == for DataAbstract (implemented in the children) so you can use <algorithm> functions to sort or search your vector.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
c preprocessor commands & return types(?) kpachopoulos Programming 4 12-06-2005 09:18 AM
Keyboard types u instead of calutateo Linux - Hardware 1 12-04-2005 03:15 AM
Types jhbumby Linux - Newbie 4 10-19-2005 06:47 AM
Sort Types k1ll3r_x Programming 2 01-15-2005 12:55 AM
Ram types Ryan450 Linux - Hardware 11 10-16-2004 06:56 AM


All times are GMT -5. The time now is 01:43 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration