C ++中接口的高效替代方案

时间:2014-04-03 20:35:30

标签: c++ design-patterns interface

在C ++中,我有一个类,它暴露了两个(或更多)不同的重叠接口。它是一个中央数据存储和信号提供商。

摘要非常简化的例子,实际上会有更多的getter和setter:

class IXY
{
public:
   virtual int GetX(int) = 0;
   virtual int GetY(int) = 0;
}

class IX
{
public:
  virtual int GetX(int) = 0;
}

class A : public IX, IXY
{
    // ... implement getter and others
}

另一方面,我有另外两个类,每个类只需要访问一个接口,以防止意外不合理的数据不应该使用。它们只会获取接口指针,并且只能访问此指定的接口。但是,如果存在许多不同的重叠接口和存储器关键嵌入式系统,则不需要虚拟功能表。幸运的是,编译器可以优化它,但不能保证。

还有别的东西可以做,有些漂亮的设计模式吗?我只能想到丑陋的定义修改不同包含的getter的可见性(私有,公共),但这不是很好。或者使用define来使用接口进行静态测试,只使用所需的接口,而不是完全使用接口进行真正的编译步骤。

2 个答案:

答案 0 :(得分:1)

A类可以拥有完全私密的界面,并将IX和IXY声明为朋友。

class A {
  private:
    int GetX() { return m_x; }
    int GetY() { return m_y; }
    int m_x;
    int m_y;
    friend class IX;
    friend class IXY;
 };

IX和IXY可以是维护指向A类实例的引用或指针并提供功能的实现,而不是抽象接口。

 class IX {
   public:
     explicit IX(A &a) m_a(a) {}
     int GetX() { return m_a.GetX(); }

   private:
     A &m_a;
 };

 // similar for IXY

有效地共享常用方法的实现。 “接口”中的简单转发方法可能会被优化,直接调用A中的相应方法。仍然可能存在间接性,你可能只是为了vtable空间而没有代码空间,但它确实给了一个很好的控制提供给其他对象的接口的方法。

答案 1 :(得分:0)

如果在运行时不需要动态调度但可以在编译时指定实际类型,则可以坚持使用静态多态。静态多态性至少有三种方法。

  • 创建客户端类模板类,然后将它们传递给对象。
  • Curiously recursive template pattern (CRTP)
  • 使用函数式编程方法,让客户端使用std :: function对象。不是为每个客户端定义两个抽象接口,一个是成员函数f,另一个是成员函数g,为每个客户端传递一个std :: function参数,然后调用该对象上的成员函数。