Object of any type

This is a discussion on Object of any type within the C++ Programming forums, part of the General Programming Boards category; With all this PHP programming I've been doing lately, I've been thinking about writing a class that acts like it's ...

  1. #1
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856

    Object of any type

    With all this PHP programming I've been doing lately, I've been thinking about writing a class that acts like it's variables. For those who are completely unfamiliar with PHP, you can assign essentially any type to a variable. For example:
    PHP Code:
    $somevar 123;
    $somevar "a string!";
    $somevar = new array();
    $somevar[0] = 456;
    $somevar[1] = "another string"
    This is a very neat magic trick and I thought it would be fun to implement something like that myself in C++. I am completely unaware if there is already something like it already exists for C++ (even if it does I'd like to do it myself), but if there is I'd like to know about it.

    Basically why I'm telling you all this is that I'm in the middle of implementing it and all is going well. You can assign any primitive type to an object and cast from any type to another. You can even have an array of mixed types; here's a line from my testing (It's really neat stuff):
    Code:
      Morph arr[COUNT] = { "null", 1, "Three3", 4444, 'X', 3.14159f, UINT_MAX, str, wchar_t(65535) };
    Anyway, as I'm getting deeper into it things are getting more complicated. For example, if you want to assign an array you can use a constructor that also accepts the number of elements and a copy is made on the heap for the object. Now I'm thinking that you should also be able to assign an object to a pointer (just pointing, not copying). What issues come to mind when you contemplate building such a class? I still haven't given much thought to how it will handle being assigned user-defined types and such. Right now the class is so filled with templates and explicit specializations that it's sort of depressing to look at. There are some complications and problems I don't understand, but I'm saving that fun for later.

    If you have any thoughts on how such a class should be implemented or on some things that one shouldn't forget (special cases, etc), please share them.

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Hmm, I would imagine that the class would have to variables:
    1) A void pointer to the area where the object is stored
    2) The type

    You would need a constructor for whatever types you wanna use. Then if they want to do say operator+ you just cast the pointer and pass on the parameters

  3. #3
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    That is basically what I'm using. I store a void*, the size of a single element (to help determine it's type), the number of elements we're pointing at (0 for a single variable, >0 for an allocated array, and UINT_MAX for a pointer to somewhere else), and whether or not it is signed. I use all this data to determine the object's type and so on, but it is not very attractive at all because in order to determine if it is signed/unsigned I have to have all sorts of ugly specializations just for the unsigned's so I can set the internal "signed" variable to false.

    Either way, what you've suggested is pretty much what I'm doing. Have you any other thoughts with regard to the more nitty-gritty innerworkings? I'm talking pointers, arrays, operator*, operator[], operator&, etc.

    Some tricky things are, for example, that you can cast to a const char* and regardless of the actual type it will return a string with the value, but if you cast to a char* for a numeric value nothing good is returned because there is no accessible char* for the user to touch. Another is operator[]. You can use it to retrieve a variable, but you can't use it to return a reference. With operator& should you return the address of the void* or ? Depending on the actual stored type, lots of different do lots of different things and all these decisions are based on the size of an element (that doesn't feel too safe). Many things to ponder...

  4. #4
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Hmmmmm... Im just a beginner for 4 years LOl off and on, I really suck at programming, and this topic intrigues me. I always wanted to do what you are talking about. Never thought of comparing the sizes to see what data type it is. but I think Im reading.
    I tried to make code. but some of the data types are the same size. so I dont know how it would work.
    like the size of and int is 4 and float is 4 and long is 4.
    Code:
    
    #include <iostream>
    using namespace std;
    
    
    int main(){
    int a;
    char b;
    float c;
    double d;
    long e;
    
    cout<<"sizeof(a)= "<<sizeof(a)<<"sizeof(b)= "<<sizeof(b)<<"sizeof(c)= "<<sizeof(c)
    <<"sizeof(d)= "<<sizeof(d)<<"sizeof(e)= "<<sizeof(e)<<endl;
    
    system("PAUSE");
    return 0;
    }
    well take care byebye

  5. #5
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    See that is one of the caveat's I'm talking about (and a very dirty one to work around). As far as int and long go, it doesn't matter which one you use to manipulate/print the value because they represent the same number (when they are the same size). Now float is another thing altogether. If you use a float, the class internally thinks it's a double since a double is 8 bytes, and doing that causes a lot of other little issues (like when printing, casting, etc).

    It is really a messy thing to do, using templates and explicit specialization and such, and I'm thinking of forgetting all that and just coding an assignment operator for every built-in type. So instead of a template <typename T> Morph(T val); I would have Morph(int val); Morph(short val); Morph(unsigned int val); ... You can see why I didn't (and still don't) want to do that, but if I do it will provide me the luxury of knowing without a doubt what type the user is trying to use. Although I'm still unsure about how I'd go about handling user-defined data types. Maybe I'll just skip them altogether. Anyone have any ideas about how you could go about casting a void* to a user-defined class without ever possibly knowing the class before-hand?

  6. #6
    Registered User Kybo_Ren's Avatar
    Join Date
    Sep 2004
    Posts
    136
    This can be pretty simple to do in C++.

    Suppose you have $varname = <value>

    With C++, you can use RTTI to get the type of the object, or you could define the type yourself using reasoning. Here's a very inefficient way:
    1. Create a std::map mapping the var names to a class you define
    2. That class you define simply allocates a new object of the type the value is on the heap. The destructor can be useful for deallocating. The class defines all the operators you need for an object (simply deferring it to the object's inherent operators).

    Maybe I'll try it out later.

    EDIT: In case I wasn't clear, here's what I mean:
    The interpreter sees the expression $varname = 12345;. It takes '12345' and interprets it (no quotes, all numbers == integer type). It sees it's an integer and creates a new std::map pair <"varname", CVar>. Then it does what it needs to in the CVar object. The class has this:

    Code:
    class CVar{
        void *ptr;//pointer to the object we will create
        std::string type;//the type of the object to create
    public:
        CVar(){};
        //blah blah blah, implement copy constructor for $var1 = $var2, destructor, etc.
    };
    Yes, you need to know the type, but you can figure it out and do something like that.
    Last edited by Kybo_Ren; 02-16-2005 at 04:57 PM.

  7. #7
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Yea I was thinking about putting the value in an array and parsing it to find out what data type that is. That seems like the best chokce for me. Take care all

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Just for reference, Boost.Any and Boost.Variant are two classes that represent such stuff.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Thanks for the reference CornedBee. I've read through those classes and have implemented a class like ("like" meaning "identical to") the Any class. It's implementation is very interesting, however it doesn't actually accomplish what I'd like it to. The best thing about it is how it allows you to assign any type of variable to it. The problems I have with it are that you can not assign any variable to it (two-dimensional arrays and such don't compile, understandably) and if you assign it an array it just takes on the value of the pointer instead of allocating a copy. Perhaps I'm asking too much (it certainly appears that way), and if so I'm just going to give up on it. It seems some of the concepts I'm trying to implement just cannot be written with C++.

  10. #10
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    Is'nt a template kinda like that? where you put type and you can put any data type in the spot? I might try and make my own beginner implementation of a class like this. and show you guys maybe if I do it. Kinda seems hard though so I don tknow if I can do it. I have the same problem. Every idea I try programming is either too complex or cant be done LOL.
    Take care all.

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Well, I believe that it would be best, given that you're already dealing with advanced C++, to simply give up the raw types. Use vectors instead of arrays, std::strings instead of C-style strings etc.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Registered User
    Join Date
    Nov 2004
    Posts
    49
    I made a small program that tells if a data is a float or not. GO ME LOL
    Tell me what you think Lol thanks

    Code:
    #include <iostream>
    using namespace std;
    string Data="324.234";
    bool f;
    char fdot='.';
    int fcount=0;
    int main(){
    
    
    for(int i=0;Data[i]!='\0';i++){
    if(Data[i]>='0' && Data[i]<='9' && fcount<2){
    	cout<<"first condition"<<endl;
    f=true;
    }
    else if(Data[i]==fdot && fcount!=1){
    	cout<<"second condition"<<endl;
    fcount++;
    }
    else if(Data[i]==fdot && fcount==1){
    	cout<<"thrid condition"<<endl;
    f=false;
    break;
    }
    else{
    	cout<<"fourth condition"<<endl;
    f=false;
    break;
    }
    
    }
    cout<<f<<endl;
    
    system("PAUSE");
    return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting the matrix question..
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-22-2008, 03:17 PM
  2. Creating a map with a new object type
    By blacknail in forum C++ Programming
    Replies: 6
    Last Post: 11-24-2008, 10:16 AM
  3. typename madness
    By zxcv in forum C++ Programming
    Replies: 4
    Last Post: 05-13-2006, 11:35 PM
  4. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 09:57 AM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 07:49 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21