3

我通过确保继承层次结构中的类实现虚拟读写功能来实现序列化:

class base
{
     ...

     virtual void read(std::istream&)=0;
     virtual void write(std::ostream&) const=0;
     virtual std::string is_a() const;
};

BEGIN_NAMESPACE_1(io)
    SERIALISE(base)
END_NAMESPACE_1

其中宏“SERIALISE”实现了“serialise”和“deserialise”函数的重载,以允许通过基类指针轻松输入/输出:

#define SERIALISE(TYPE)\
void deserialise( boost::shared_ptr<TYPE>& dat, std::istream& ifs )\
{\
    std::string type;\
    read(type, ifs);\
\
    dat = TYPE::make_##TYPE(type);\
    dat->read(ifs);\
}\
\
void serialise( const boost::shared_ptr<TYPE>& dat, std::ofstream& ofs )\
{\
    write(dat->is_a(), ofs);\
    dat->write(ofs);\
}

但是,如果基类包含纯虚函数,我会收到编译器错误“无法分配抽象类型“基”的对象,因为以下函数在“基”中是纯的......”,大概是因为编译器试图实例化抽象类名传递给宏调用时的基类。有没有办法挽救这个 i/o 设计?

4

1 回答 1

1

您不能实例化抽象基类或将其用作函数的值参数。

模板显式 shared_ptr(Y * p); 要求:p 必须可转换为 T *。Y 必须是完整类型。表达式 delete p 必须是格式正确的,不能调用未定义的行为,也不能抛出异常。

效果:构造一个拥有指针 p 的 shared_ptr。

后置条件:use_count() == 1 && get() == p。

抛出:std::bad_alloc,或者当无法获取内存以外的资源时发生实现定义的异常。

异常安全:如果抛出异常,则调用 delete p。

注意: p 必须是指向通过 C++ new 表达式分配的对象的指针,或者为 0。即使 p 为 0,使用 count 为 1 的后置条件也成立;对值为 0 的指针调用 delete 是无害的。

在这种情况下,编译器不必将模板 shared_ptr 解析为内部具有 TYPE 类型的值,因为它们永远不能被实例化。

于 2012-10-22T15:30:03.033 回答