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.
精彩评论