C ++类成员隐藏规则:设计问题

时间:2011-05-10 01:32:49

标签: c++ interface

我有一个基类,Message,它决定了政策。我还为特定的消息实例推导了该类。

考虑这个简化的例子:

template< ::size_t MessageSize >
struct Message {
    enum { size = MessageSize };
    Bits< ChunkSize > bits_[size / ChunkSize];
    // Defines behavior for the Message types
};

template< ::size_t MessageSize >
struct SmallMessage : public Message< MessageSize > {
    Bits< MessageSize > bits_;
};

// other derivations of Message...

template< class MessageType, ::size_t MessageSize >
struct MakeMessage {
    typedef typename IfElseType<
            MessageSize < ChunkSize,
            SmallMessage< MessageSize >,
            Message< MessageSize >
        >::type type;
};

如果ChunkSize为32,我会生成以下内容:

MakeMessage< FooMessage, 16 >

Message< 16 >将导致Bits< 32 > bits_[0];,而SmallMessage< 16 >将包含Bits< 16 > bits_,据我了解,这将遮蔽原始的零大小成员。

我知道有几种方法可以解决这个问题:

  1. 声明bits_以外的名称,并提供覆盖该
  2. 的界面
  3. 修改SmallMessage以隐藏Message处理bits_本地实施的所有方法
  4. Message虚拟
  5. 中制作方法

    我的问题是这两种方法是否有好处,或者是否有更好的方法为各种大小的内存容器提供接口,如上所述。

    归根结底,我想要有以下几点:

    typedef MakeMessage< FooMessage, 16 >::type message_type;
    // ...
    message_type message;
    message.doSomethingToBits ();
    

    无论实际使用什么容器,都要正常工作。

1 个答案:

答案 0 :(得分:0)

好吧,尽管我可以通过大量的templatetypename进行锻炼,但您尝试使用继承进行合成,这被认为是错误的方法。 SmallMessage此处类型为Message,因为您注意到它不支持以相同方式处理bits_数组。

我认为正确的方法是将Message作为抽象基类(重要的是:没有 bits_任何类型,可能是很多纯虚拟函数),然后SmallMessageBigMessage作为实现。此外,由于您无论如何都在使用模板,因此类型是在编译时计算出来的,实际上根本没有理由可以使用Message。只要SmallMessageBigMessage具有相同的签名,即使它们没有公共基类,您也可以使用message_type进行描述。您需要基类Message的唯一原因是,如果您想使用后期绑定更一般地讨论消息。虽然拥有基类也将静态强制签名在声明中匹配,而不是给出奇怪的错误......有时......在代码的远端部分,因为你在其中一个类中错误地声明了一个方法(但不是其他)。

这是一个安全的赌注,你也希望BigMessage::bits_[(size-1) / ChunkSize + 1],这只是天花板而不是地板。这样你实际上有足够的Bits es来适应你所有的位。