我有一个C++类,它实际上是一个容器:

class SimpleContainer {
   public:
       // Various accessor methods / iterators
   private:
       // The actual content
}

除了SimpleContainer之外,我还想创建一个StrictContainer,它通过在内容上实现规则来在语义上扩展SimpleContainer,但要使用与现有SimpleContainer实例相同的内容。
class StrictContainer : public SimpleContainer {

     StrictContainer( const SimpleContainer& simple ) {
         // Check content in simple, and raise an exception
         // if it is not valid.
     }
}

现在-我的问题是SimpleContainerStrictContainer之间应该建立什么样的关系:

是-:
看起来很自然;这就是我在继承中指出的内容,但是随后我将基于扩展的StrictContainer实例后期构造创建一个SimpleContainer实例-可能吗?

has-a
或者,我可以将它实现为has-a关系,其中StrictContainer具有SimpleContainer成员,但是随后,我将需要再次在StrictContainer中实现所有访问器和迭代器,然后转发到SimpleContainer实现。

容器很大。创建StrictContainer时,我真的不会复制内容。我想我想要的是一种实现我自己的下垂运算符的方法:
SimpleContainer simple;
// Fill simpleContainer

{
    StrictContainer* strict = downcast<StrictContainer>( simple )
    ...
}
downcast<StrictContainer>在哪里调用StrictContainer上的方法以验证simple输入参数的内容?

最佳答案

因此,重申您的要求:

  • StrictContainerSimpleContainer具有相同的界面,
    与补充。 (这意味着是-与的关系
    介面)。
  • 不需要新的StrictContainer复制SimpleContainer内容。 (这意味着使用句柄进行分解。)

  • 假设原始SimpleContainer的生存期跨过StrictContainer,这听起来像decorator pattern。因此,如果您愿意做一些分解,那么如何定义这样的接口(interface)呢?
    class MyInterface {
      // No contained state needed at all.
    public:
      virtual ~MyInterface() {}
      virtual bool getThing1() const = 0;
      virtual int  getThing2() const = 0;
      // and so on...
    };
    
    class MyDecorator : public MyInterface {
        MyInterface &m_impl; // Could use a smart pointer, if available.
    public:
        MyDecorator( MyInterface &impl ): m_impl(impl) {}
        bool getThing1() const override { return impl.getThing1(); }
        int  getThing2() const override { return impl.getThing2(); }
        // and so on...
    };
    

    然后是您的具体实现:
    class SimpleContainer : public MyInterface {
        bool m_thing1;
        int  m_thing2;
            ... // All the real state goes here.
    public:
            ... // All the interface methods go here.
    };
    

    然后,StrictContainer是一个轻量级的容器,它保留原始SimpleContainer的句柄,而不是完整副本。
    class StrictContainer : public MyDecorator {
        // Additional state, if needed.
    public:
        StrictContainer( SimpleContainer &base ): MyDecorator(base) {}
        // Additional methods (like your additional validation method.
    };
    

    不需要特殊的“向下运算符”,因为您已经需要调用StrictContainer的构造函数,并且它已经完成了您需要的一切。
    SimpleContainer simple( ... );   // Construct as normal.
    StrictContainer strict = simple; // Assuming no extra arguments needed.
    

    很简单

    是的,您需要在装饰器类中的一次为接口(interface)编写每个方法的委托(delegate)操作。但是您可以定义StrictContainer类的多个变体而不必再次实现它们(除非希望覆盖其中的一些变体)。

    09-07 07:09