different abstract return types.......

Started by
7 comments, last by GOOSEDUMP 22 years, 7 months ago
I was kinda wondering if it was possible to create a situation where two child classes of an absract base class returns different types from the same method call..... ex int child1::foo() { } char* child2::foo() could this be implimented in a way such that the abstract base class does not know the return type of foo()? base* var = new child1(); var->foo(); //returns some int base* var2 = new child2(); var->foo(); //returns some char* One solution would be that foo() is not in the abstract base class so that child1 and child2 could impliment them separately. To access them, you would have to cast... ((child1*)var)->foo(); ((child2*)var2)->foo(); I wonder if their is any elegant way to do this. The situation I was thinking of was encapsulating different storage types into a common interface so calling a Get() would return its dynamic type''s variable... For example, if you have an engine that accepts 2 different internal data types (to do whatever) but loads from the same file on disk (assume you can specify what type of file to convert to, for engine use).. how can this problem be solved? Templates? How?
Advertisement
why would you have to cast? ive never had to for something like this.
(http://www.ironfroggy.com/)(http://www.ironfroggy.com/pinch)
Sounds like you want to use templates. You don''t need a class hierarchy then.

I suspect you want something like this:

  template<typename T>class Thing{    protected:        T item;    public:        Thing(T i) : item(i) {}        T Get() const { return item; }        void Set(T i) { item = i; }};// Now, to use it...void main(){    Thing<int> i(5);    int j = i.Get(); // Returns an int.    Thing<double> k(3.14159265358979);    double l = k.Get(); // Returns a double.}  
note that this is what I really want......

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

not

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

err, however the code might be for template pointers....

I want the abstract base class to be independant of the type the child has... mabey something like this....

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

if its even possible, trying to test it but finding a couple errors, not too sharp on template programming yet....
note that this is what I really want......

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

not

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

err, however the code might be for template pointers....

I want the abstract base class to be independant of the type the child has... mabey something like this....

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

if its even possible, trying to test it but finding a couple errors, not too sharp on template programming yet....
BLAH!!! that didn''t come out well....... sorry guys...
how do you do that nifty code box? how do you display the less than and greater than without itt being interpreted as tags? Bit of a newbie on forums... but anyways,

I shall use curly brackets in place of sharp ones.......

base* var = new child1();
var->foo(); //returns some int

base* var2 = new child2();
var->foo(); //returns some char*

NOT

base{int}* var = new child1();
var->foo(); //returns some int

base{char*}* var2 = new child2();
var->foo(); //returns some char*

however the code might be for templates.... I was thinking of something like this.... if its posssible...

base* var = new child1{int}();
var->foo(); //returns some int

base* var2 = new child2{char*}();
var->foo(); //returns some char*

any takers?
To get the code box, use [ source ] and end with [ /source ] (without the spaces between the brackets and words).

In answer to your question, the last method you listed is only possible if you don''t declare foo in the base class. Because you want foo to have multiple return types and use the same parameters each time, you have to use templates wherever foo is declared.

From what you described in the original post, I don''t understand why you want child classes at all. If you use templates, there is really no reason for them. If you were hoping to have a base class pointer stored somewhere so you could choose the type at runtime, then perhaps you could have foo return void*. Then you would have to typecast it into what you want when you use it.

For example:

  class Base{    public:       virtual void* foo() = 0;};class child1 : public Base{    protected:        int i;    public:       void* foo() {  return &i }};class child2 : public Base{    protected:        char* str;    public:       void* foo() {  return str; }};// To use it...void main(){    Base *base;    if (useInt)    {        base = new child1;        int i = *((int *)base->foo());    }    else    {        base = new child2;        char* s = (char*)base->foo();    }}  


Or you could use an enumerated type or something to store all the possible return types, then set that instead of instantiating a base class pointer. Then you could use templates by merely checking to see what the value of the enumerated type variable is and create a template accordingly.
I guess one way you can do this would be to encapsulate return value into an object and provide casting operator within the object;
     Base *b1 = new Child1()   Base *b2 = new Child2()   try{      int x = (int)(b1->Get());      char* y = (char*)(b2->Get());   } catch(...)   {      cerr << "Invalid cast or something" << endl;   }  
thanks guys/gals....... actually, those were exactly the way I was thinking of, just wondering if their were any other "tricks" that I don''t know about.... cool, Thanks!

This topic is closed to new replies.

Advertisement