2011年12月18日日曜日

Plain Old Data

POD(Plain Old Data)とは

Cの構造体のように、連続したバイトデータで表現できる型のことをPODと呼びます。

PODには、intやdoubleなどデフォルト提供されている型と、classやstructで定義するオリジナル型があります。

POD Classの条件

C++11では、PODの条件として"trivialでありstandard-layoutであり、すべての非staticメンバがPOD型である"としています。

trivialであるclassやstructとは、以下の条件を満たしている型になります。

  • コンパイラが定義したデフォルトコンストラクタを持っていること
  • コンパイラが定義したコピーコンストラクタを持っていること
  • コンパイラが定義した代入演算子を持っていること
  • コンパイラが定義した非virtualなデストラクタを持っていること

standard-layoutなclassやstructとは、以下の条件を満たしている型になります。

  • すべての非staticメンバがstandard-layoutな型であること
  • すべての非staticデータメンバが同じアクセス制御であること
  • 仮想関数を持たないこと
  • 仮想基底classを持たないこと
  • すべての基底クラスがstandard-layoutな型であること
  • はじめに定義した非staticなデータメンバの型と同じ型の基本classを持たないこと
  • 継承していて、派生classが非staticなメンバーを持っている場合、基本classが非staticなメンバーを持っていないこと
  • 継承していて、基本classの一つが非staticなメンバーを持っている場合、派生classおよびその他の基本classが非staticなメンバーを持っていないこと

PODを使う理由

PODを定義することで、Cとデータの受け渡しが可能になります。

また、memcpyなどの関数などにより効率的なデータ処理を行えます。

サンプル

単純なPOD class

class Point {
  unsigned int _x;
  unsigned int _y;
public:
  unsigned int x() { return _x; }
  unsigned int y() { return _y; }
};

単純なPOD struct

struct Point {
  unsigned int x;
  unsigned int y;
};

継承する場合 その1

class Base {
public:
  int sum(int a, int b) { return a + b; }
};
class POD : public Base {
  // Baseクラスが非staticなデータメンバを持っていないので、
  // このクラスでは非staticなデータメンバを持つことができる。
  int _a;
  int _b;
public:
  int a() { return _a; }
  int b() { return _b; }
  int sum() { return Base::sum(_a, _b); }
};

継承する場合 その2

class Base {
  int _a;
  int _b;
public:
  int a() { return _a; }
  int b() { return _b; }
};
class POD : public Base {
  // Baseクラスが非staticなデータメンバを持っているので、
  // このクラスでは非staticなデータメンバを持つことはできない。
public:
  int sum() { return a() + b(); }
};

TODO

  • 定義した型がPODであるかを判定する方法
  • PODの条件を満たしていないサンプルを追加

0 件のコメント:

コメントを投稿