C++ C++;通用数据类型

C++ C++;通用数据类型,c++,C++,我有一个通用数据类型,它通过值传递,但不维护类型信息。我们只在其中存储指针和基本数据类型(如int、float等)。现在,我们第一次需要将std::string存储在这个文件中。所以我们决定将其转换为std::string*并存储。然后是破坏问题。我们不希望每次都复制std::字符串。因此,我正在考虑这样一种方法。假设数据类型如下所示 class Atom { public : enum flags { IS_STRING, IS_EMPT

我有一个通用数据类型,它通过值传递,但不维护类型信息。我们只在其中存储指针和基本数据类型(如int、float等)。现在,我们第一次需要将std::string存储在这个文件中。所以我们决定将其转换为std::string*并存储。然后是破坏问题。我们不希望每次都复制std::字符串。因此,我正在考虑这样一种方法。假设数据类型如下所示

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;
        }
    }
};
类原子
{
公众:
枚举标志
{
是一根绳子,
你是空的,
你收到复印件了吗,
标记
};
私人:
void*m_值;
std::位集m_标志;
公众:
.....
Atom(Atom&atm)
{
atm.m_flags.set(已复制);
..... 
}
.....
~Atom()
{
if(m_flags.test(IS_STRING)和&!m_flags.test(是否已复制))
{
std::string*val=静态_转换(m_值);
删除val;
}
}
};
这是确定是否不再引用std::string*的好方法吗?有什么意见吗

我已经研究了boost::any和poco::DynamicAny。因为我需要序列化,所以我不能使用它们

谢谢,
Gokul.

我认为你应该研究一下使用boost::shared_ptr(或std::tr1::shared_ptr)的可能性。

你可能想在谷歌上输入“写时拷贝”并阅读这个主题。它通常是如何实现的,它的用途是什么,它的缺点是什么


你看过吗

除了这种“通用数据类型”是否是一个好主意之外,如果您没有复制字符串,这个类能否确保它拥有它的指针指向的字符串?您能否保证只有通过
new
分配的字符串才会传递给类以获得所有权


这个类的设计似乎有问题。

我第一份工作的第一个任务就是设计一个变体类。您可以在这里找到一些基本代码(和讨论)


因为您还需要序列化,所以您可能对库感兴趣。我认为它提供的正是您想要的:可以是字符串、bool、int、数组、对象等的数据类型。。。(类。)

这种方法的一个主要缺陷是,您确实需要一个引用计数,而不是一个“已复制”标志位。如果将字符串复制多次,该位将不起作用。如前所述,如果创建Atom的副本并在原始副本之前删除副本,您将遇到麻烦:

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;
原子a(“你好世界”); 如果(…){ 原子b(a); //b被销毁,删除字符串 } //哦,字符串已被删除,但a仍在引用它。

这是一种传递值数据类型。我认为您的建议对于传递引用数据类型是有效的。他的建议对于可复制的传递值类是有效的。显然,不可复制的pass-by-reference类型没有复制问题。我的意思是使用shared_ptr跟踪std::string*并在适当的时候释放。如果一个包含std::string的Atom被复制了好几次,而原始实例的生存期最长,那么您的代码将如何处理这种情况?我只需要确保在没有引用的情况下数据会被删除。@Andres::当我有一个传递值数据类型时,这种情况会发生吗??通常它会从一个函数传递到另一个函数,并通过赋值进行复制。它不能在这里使用,因为我们需要对它进行序列化。@Gokul:你的类型不是免费提供序列化的,你也必须自己实现。如果你把你的基础放在<代码> Boost:任何,至少你有一个坚实的基础。是的,我只会有那个构造函数而没有设置语句。@ Gukul--这不是真正的问题。你能确定调用构造函数的人只会使用通过
new
分配的字符串,并且调用方随后不会调用
delete
?这些规则很难在您的设计中强制执行,因此在提交此类设计之前考虑这些规则可能是一个好主意。抱歉,我没有提到它,但人们只会将其作为std::string传递,我会将其转换为std::string*。所以我需要释放它。如果它作为std::string*传递,那么就不必担心释放它了。您看过boost::variant吗?序列化如何影响boost::any的使用?(我从未尝试过poco::DynamicCany)为什么不在它将包含的对象类型上使用模板Atom呢?@George:这不是一种数据类型,也不起作用。谢谢。。我明白了。但是我无法使用boost::any,因为它不支持boost序列化。您可以将序列化添加到类中(正如您现在所做的那样),并在内部使用boost::any或boost::variant@David:如果我不能存储类型信息,我不想支付boost::any的费用(通过将所有内容转换为void*,然后将其放入boost::any中)。目前,我正在通过将数据作为字节流进行序列化,长度为。您如何知道必须如何解释反序列化的元素?使用boost::any方法(内存、序列化信息)无法支付的成本是什么?@David:boost::any对每个数据提取、每个复制构造函数调用、每个析构函数调用都有虚拟函数调用,它甚至涉及对简单数据类型的动态分配stranger,请在投票时解释:)