ikautak.log

C/C++, Python, CUDA, Android, Linux kernel, Network, etc.

C++のためのAPIデザイン 5章〜6章

C++のためのAPIデザイン

C++のためのAPIデザイン

  • 作者: マーティン・レディ,Martin Reddy,三宅陽一郎,ホジソンますみ
  • 出版社/メーカー: ソフトバンククリエイティブ
  • 発売日: 2012/11/02
  • メディア: 大型本
  • 購入: 4人 クリック: 106回
  • この商品を含むブログ (8件) を見る

次に読もうと思ってる IT技術者なら知っておきたい ストレージの原則と技術 をブークスで頼んでるけど時間かかりそうだな…

第5章 スタイル

APIの4つのスタイルについて。

フラットC API

CとC++双方で動くAPIを設計可能。

オブジェクト指向C++ API

クラスと継承が使えるが、複雑が増すかも。

テンプレートベースAPI

静的なポリモーフィズムが実現できる。作成されたクラスがすべて同じインターフェイスを持つ。
クラステンプレートの定義がパブリックヘッダにないとまずいので、API設計にとって良くない。
コード量も増える。

データ駆動API

1つのインターフェイスで、コマンドとデータを送るようなwebサービスのようなAPI
APIの変更に強い。多くの場合、コマンドの追加・削除・変更を行なってもAPIシグネチャに影響がない。
リアルタイムの処理には向かない。

第6章 C++の使用法

constメソッドはメンバ変数を変更できないが、ユーザに影響のない変更であればメンバ変数をmutableにする方法もOK。

class HashTable
{
public:
    void Insert(const std::string &str);
    int Remove(const std::string &str);
    bool Has(const std::string &str);
    int GetSize(void) const;
    ...
private:
    mutable int mCachedSize;
    mutable bool mSizeIsDirty;
    ...
};

// サイズを取得するだけなのでconstにしたいが、サイズ計算を遅延させるため
// メンバ変数を変更するのでmutableにする。
int HashTable::GetSize(void) const
{
    if (mSizeIsDirty) {
        mCachedSize = CalculateSize();
        mSizeIsDrity = false;
    }
    return mCachedSize;
}


戻り値がオブジェクトの内部状態を参照している場合は、constを付ける。

テンプレートの定義を公開しないために、実装を別ヘッダファイルにする方法がある。

// stack.h
#ifndef STACK_H
#define STACK_H
#include <vector>

template <typename T>
class Stack
{
public:
    void Push(T val);
    T Pop();
    ...

private:
    std::vector<T> mStack;
};

// すべての実装を別ヘッダに隔離
#include "stack_priv.h"
#endif
// stack_priv.h
#ifndef STACK_PRIV_H
#define STACK_PRIV_H

template <typename T>
void Stack<T>::Push(T val)
{
    mStack.push_back(val);
}
...

#endif


.cppに書いた変数・関数もユーザが勝手にextern宣言することでアクセスできしまう。staticか、匿名のnamespaceで囲む。

char *a と char* a って後者一択だと思ってたけど前者押しの人もいるのか。自分は「charポインタ型」のaだという意識が強いな。