隐藏C ++中的实现细节

时间:2019-07-18 09:35:13

标签: c++ pimpl-idiom method-hiding

我想从标头中定义的接口中隐藏实现特定的细节,以便在进行更新时代码可维护且编译起来更快(尽管我没有后者的统计信息)。

但是,我不能在2003年以后使用动态内存或c ++(否11/14/17)。我也不能使用Boost等库。该应用程序是实时嵌入式的,因此效率至关重要。有问题的代码与硬件紧密耦合。

我在此处查看了几篇建议使用PIMPL习惯用法的帖子,但是间接和动态内存似乎禁止了这种用法。一种选择是预分配类并设置指针,但这似乎不灵活。

下面是一个过于简化的示例,仅在实现文件中使用函数和静态变量;是否存在与封装或编译过程有关的问题?给定约束,我还能如何实现上述目标?

标题中包含详细信息的示例:

#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;
}

1 个答案:

答案 0 :(得分: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;
    }
}
相关问题