开发者

C++ universal data type

I have a universal data type, which is passed by value, but does not maintain the type information. We store only pointers and basic data types(like int, float etc) inside this. Now for the first time, we need to store std::string inside this. So we decided to convert it into std::string* and store it. Then comes the problem of destruction. We don't like to copy the std::string every time. So i am thinking of an approach like this. Say the data type looks like this

class Atom
{
public :
     enum flags
     {
         IS_STRING,
         IS_EMPTY,
         HAS_GOT_COPIED,

         MARKER
     };

private:
     void*   m_value;
     std::bitset<MARKER>   m_flags;

public:
    .....
    Atom( Atom& atm )
    {
     开发者_运维技巧   atm.m_flags.set( HAS_GOT_COPIED );
        ..... 
    }
    .....
    ~Atom()
    {
        if( m_flags.test(IS_STRING) && !m_flags.test(HAS_GOT_COPIED) )
        {
             std::string*  val = static_cast<std::string*>(m_value);
             delete val;
        }
    }
};

Is this a good approach to find out whether there is no more reference to std::string*? Any comments..

I have looked at boost::any and poco::DynamicAny. Since i need serialization, i can't use those.

Thanks, Gokul.


One major flaw with this approach is that you really need a reference count, not a single bit "has been copied" flag. The bit won't work if you copy the string multiple times. As written, you will get into trouble if you create a copy of an Atom and delete the copy before the original:

Atom a("hello world");

if (...) {
    Atom b(a);
    // b is destroyed, deleting the string
}

// Uh oh, the string's been deleted but a is still referencing it.
cout << (string) a;

I would not re-invent the wheel. If boost::any doesn't work out of the box you could still use it internally in place of your m_value field to store the data for your Atom class. That would take care of all the construction/copying/destruction details for you.


I think you should look into the possibility of using boost::shared_ptr (or std::tr1::shared_ptr).


You might want to feed "copy on write" into google and read up on the topic. How it is usually implemented, what it is used for, and what its drawbacks are.

And have you looked at boost::any?


One of my first tasks at my first job was to design a variant class. You can find some basic code (and discussion) here in this comp.lang.c++.moderated post.

Since you also need serialization, you might be interested in the JsonCpp library. I think it offers just what you are looking for: a datatype that can be a string, bool, int, array, object, etc... (the Json::Value class.)


Aside from whether this kind of 'universal data type' is a good idea, if you're not copying the string, can this class be sure that it owns the string it has pointer to? Can you guarantee that only strings allocated via new will be passed in to the class to take ownership?

The design of this class looks as though it will be problematic.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜