强制执行模板的方法定义

Enforcing method definition for templates

本文关键字:方法 定义 强制执行      更新时间:2023-10-16

我想创建一个小型库,用于使用不同协议进行序列化。因此,我创建了">接口"(小型抽象类(可序列化-然后可以序列化实现它的每个类:

class Serializable // interface
{
public:
std::string Serialize(Encoder & encoder) const
    {
    return DoSerialize(encoder);
    }
private:
virtual std::string DoSerialize(Encoder & encoder) const = 0 {}
};

另一方面,我有各种编码器的抽象版本(用于不同的编码(:

class Encoder
{
public:
Serialized GetEncoded()
    {
    return DoGetEncoded();
    }
void Encode(const std::string & data)
    {
    DoEncode(data);
    }
... other encoding functions
private:
virtual Serialized DoGetEncoded() = 0 {}
virtual void DoEncode(const std::string & data) = 0 {}
};

我用它就像:

Test1 test;
test.test = "abc";
SomeEncoder enc;
cout << "Test::Serialize: " << test.Serialize(enc) << endl;

但也许与其采用这种方法,不如在Encoder中封装模板化函数(为什么?(,如:

template<typename T>
std::string Serialize(const T & data) const
     {
     return data.Serialize();
     }
// or maybe
std::string Serialize(const Serializable & data) const
     {
     return data.Serialize();
     }

表现出更一致的行为?

我有两个问题:

  1. 哪种方法更好(在OO方面还是在一般情况下(
  2. 如果是第二种方法——我应该强制用户从接口继承,还是提供模板化版本,如果有人希望他的类型是可序列化的,他必须只编写这些方法

我最初的问题是混合的——我想问两者是否应该在同一类型中实现——强制从接口派生并使用模板化版本,但似乎没有必要,

我并没有真正连接到任何解决方案,我个人会使用最基本的接口:

struct Serializable{
   virtual std::string serialize () const = 0;
};

并让实现它的每个类处理如何进行序列化。有些类甚至不需要编码器,那么为什么要在函数签名上强制使用编码器呢?

如果serialize只是调用它并返回其返回值,那么DoSerialize看起来相当冗长,而且无论如何都需要对它进行保护才能工作。

当保持接口简单时,你不会混淆你的开发人员-他们不必理解你打算如何序列化-他们只需将他们的对象序列化为某种二进制形式。