C++ 的 idioms(十一)

inner class

如果存在两个“无关”(继承关系)的接口同名(很遗憾而且没有 virtual 的 destructor),而又需要实现两者的一个“结合体”,最好的方式不是通过继承。因为这个接口的意义会非常含混,别人必须读文档才能理解这个同名接口的表意,另一方面由于 non-virtual 的 destructor 需要避免增加成员。inner class 就是为了解决这个问题而提出的 idiom,例子来自 wikibooks

class base1 {
  virtual int open (int) {}
} ;

class base2 {
  virtual int open (int) {}
} ;

class derived {
  class base1_imp : public base1 {
    derived *p ;
  public:
    base1_imp (derived* q) : p (q) {}
    virtual int open (int j) {
      return p -> base1_open (j) ;
    }
  } base1_obj ;
  class base2_imp : public base2 {
    derived *p ;
  public:
    base2_imp (derived* q) : p (q) {}
    virtual int open (int j) {
      return p -> base2_open (j) ;
    }
  } base2_obj ;

  friend class base1_imp ;
  friend class base2_imp ;

  int base1_open (int j) {}
  int base2_open (int j) {}

public:
  operator base1& () {return base1_obj ;}
  operator base2& () {return base2_obj ;}
} ;

int
base1_open (base1& o, int j) {
  return o.open (j) ;
}

int
base2_open (base2& o, int j) {
  return o.open (j) ;
}

核心的 idea 是两个类的接口对应两个 inner class,这两个 inner class 实际上是个 proxy,他们将对应的 open 传递到 “derived” 类对应的具体实现里面,这样 derived 可以决定如何对两种情况进行封装和处理,或者引用对应类的实现。而用户使用的时候,需要分别用外部不同的两个函数进行调用以示区分,这里通过定义 conversion operator 将 inner class 对象传递出去就能得到需要的效果了。

int2type

这个是 boost.MPL 的惯用手法了

template <int I> struct integral_constant {
  enum {
    value = I ;
  } ;
} ;

interface class

嗯,Java 里面已经非常常见了,C++ 里面其实也挺常见的。定义一个抽象类,里面都是 pure virtual。(见 wikibooks 相关文章了)

iterator pair

其实和 coercion by member template 类似,容器初始化应该允许使用 iterator pair 来表示 copy 的 range,因此一般会提供一个 template 干这个事情。

template <class T, ...>
class some_container {
public:
  template <class Iterator>
  some_container (Iterator begin, Iterator end) {
    // copying
  }
} ;

making new friends

这个主要是如何为 template 引入 friend

// Forward declarations
template<class T> class Foo;
template<class T> ostream& operator<<(ostream&,
                                      const Foo<T>&);
template<class T> class Foo {
  T val;
public:
  Foo(const T& t) { val = t; }
  friend ostream& operator<< <>(ostream&, const Foo<T>&);
};

template<class T>
ostream& operator<<(ostream& os, const foo<T>& b) {
  return os << b.value;
}

需要注意很容易出错的那种写法产生错误居然是链接错误,换言之流插入甚至没有被实例化。这个原因到底是啥呢?

metafunction

这个是 metaprogramming 的精髓,前面已经有讨论,就是某些 typedef 了 type 的 struct,通过他们我们可以进行类型的运算。

——————
And he brought him forth abroad, and said, Look now toward heaven, and tell the stars, if you be able to number them: and he said to him, So shall your seed be.

Advertisements
C++ 的 idioms(十一)

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s