1

ヘッダーで定義されたインターフェイスから実装固有の詳細を隠したいので、更新時にコードを保守しやすく、コンパイルを高速化します (ただし、後者の統計はありません)。

ただし、2003 年以降は動的メモリまたは C++ を使用できません (11/14/17 は使用できません)。ブーストなどのライブラリも使用できません。アプリケーションはリアルタイムで組み込まれているため、効率が重要です。問題のコードは、ハードウェアに密接に結合されています。

PIMPL のイディオムを示唆する here のいくつかの投稿を見ましたが、間接性と動的メモリがこれを禁止しているようです。1 つのオプションは、クラスを事前に割り当ててポインターを設定することですが、これは柔軟性がないようです。

以下は、実装ファイルで関数と静的変数を使用する単純化された例です。カプセル化またはコンパイル プロセスに関連する問題はありますか? 制約が与えられた場合、他にどのように上記を達成できますか?

ヘッダーに詳細を含む例:

#ifndef HARDWARE_IF_HPP
#define HARDWARE_IF_HPP

class hardware_if
{
public:
    enum cfg_mode { standby, enable, disable };
    void configure(cfg_mode mode);

private:
    void hardware_if_standby();
    void hardware_if_enable();
    void hardware_if_disable();

    static const uint32_t CONTROL_REGISTER = 0x10000000;
    static const uint32_t ENABLED_MODE     = 2;
    static const uint32_t DISABLED_MODE    = 3;
};

#endif


// CPP

#include <cstdio>
#include <stdint.h>
#include "hardware_if.hpp"

void hardware_if::hardware_if_standby()
{
    printf("set hardware into standby state; write %X to 0x%X\n",
        STANDBY_MODE, CONTROL_REGISTER);
}

void hardware_if::hardware_if_enable()
{
    printf("set hardware into enabled state; write %X to 0x%X\n",
        ENABLED_MODE, CONTROL_REGISTER);
}

void hardware_if::hardware_if_disable()
{
    printf("set hardware into disabled state; write %X to 0x%X\n",
        DISABLED_MODE, CONTROL_REGISTER);
}

void hardware_if::configure(cfg_mode mode)
{
    switch (mode)
    {
    case standby: 
        hardware_if_standby();
        break;
    case enable: 
        hardware_if_enable();
        break;
    default: 
        hardware_if_disable();
        break;
    }
}


//

#include <stdint.h>
#include "hardware_if.hpp"

int main()
{
    hardware_if hdw;
    hdw.configure(hardware_if::enable);
    return 0;
}

実装の詳細な例:

#ifndef HARDWARE_IF_HPP
#define HARDWARE_IF_HPP

class hardware_if
{
public:
    enum cfg_mode { standby, enable, disable };
    void configure(cfg_mode mode);
};

#endif


// CPP

#include <cstdio>
#include <stdint.h>
#include "hardware_if.hpp"

static const uint32_t CONTROL_REGISTER = 0x10000000;
static const uint32_t STANDBY_MODE     = 1;
static const uint32_t ENABLED_MODE     = 2;
static const uint32_t DISABLED_MODE    = 3;

void hardware_if_standby();
void hardware_if_enable();
void hardware_if_disable();

void hardware_if_standby()
{
    printf("set hardware into standby state; write %X to 0x%X\n",
        STANDBY_MODE, CONTROL_REGISTER);
}

void hardware_if_enable()
{
    printf("set hardware into enabled state; write %X to 0x%X\n",
        ENABLED_MODE, CONTROL_REGISTER);
}

void hardware_if_disable()
{
    printf("set hardware into disabled state; write %X to 0x%X\n",
        DISABLED_MODE, CONTROL_REGISTER);
}

void hardware_if::configure(cfg_mode mode)
{
    switch (mode)
    {
    case standby: 
        hardware_if_standby();
        break;
    case enable: 
        hardware_if_enable();
        break;
    default: 
        hardware_if_disable();
        break;
    }
}

//

#include <stdint.h>
#include "hardware_if.hpp"

int main()
{
    hardware_if hdw;
    hdw.configure(hardware_if::enable);
    return 0;
}
4

1 に答える 1

3

特定のサンプル クラスには、非表示にするデータ メンバーがありません。プライベートな静的データ メンバーは、.cxxファイル内の名前のない名前空間に安全に移動できます。同じことが非パブリック メンバー関数にも当てはまります。

ただし、メモリ割り当てなしでデータ メンバーを非表示にする方法の例を次に示します。

// hardware_if.h
class hardware_if
{
public:
    hardware_if();
    ~hardware_if();

    enum cfg_mode { standby, enable, disable };
    void configure(cfg_mode mode);

    struct Impl;

private:
    hardware_if(hardware_if const&);
    hardware_if& operator=(hardware_if const&);

    enum { IMPL_SIZE = 16 };
    union {
        unsigned char storage[IMPL_SIZE];
        double align;
    };
};

// hardware_if.cxx
#include <new>

struct hardware_if::Impl {
    // The data members.
    int a, b, c, d;
};

namespace {

const uint32_t CONTROL_REGISTER = 0x10000000;
const uint32_t ENABLED_MODE     = 2;
const uint32_t DISABLED_MODE    = 3;

void hardware_if_standby(hardware_if::Impl&) { /* ... */ }
void hardware_if_enable(hardware_if::Impl&) { /* ... */ }
void hardware_if_disable(hardware_if::Impl&) { /* ... */ }

// Compiler error if IMPL_SIZE != sizeof(hardware_if::Impl).
inline hardware_if::Impl& get_impl(unsigned char(&storage)[sizeof(hardware_if::Impl)]) {
    return reinterpret_cast<hardware_if::Impl&>(storage);
}

}

hardware_if::hardware_if() {
    new (storage) Impl;
}

hardware_if::~hardware_if() {
    get_impl(storage).~Impl();
}

void hardware_if::configure(cfg_mode mode) {
    Impl& impl = get_impl(storage);
    switch(mode) {
        case standby:
            return hardware_if_standby(impl);
        // ...
        default:
            break;
    }
}
于 2019-07-18T09:42:20.143 に答える