- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想从 header 中定义的接口(interface)中隐藏实现特定的细节,以便代码可维护并且在进行更新时可以更快地编译(尽管我没有后者的统计信息)。
但是,我不能使用动态内存或 2003 年之后的 c++(2017 年 11 月 14 日之后)。我也不能使用像 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;
}
最佳答案
您的特定示例类没有任何要隐藏的数据成员。私有(private)静态数据成员可以安全地移动到 .cxx
文件中,进入未命名的命名空间,这同样适用于非公共(public)成员函数。
但这里有一个如何在没有内存分配的情况下隐藏数据成员的例子:
// 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;
}
}
关于c++ - 在 C++ 中隐藏实现细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57091431/
前言 本文主要介绍了关于MySQL主键为0与主键自排约束的关系,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 开始不设置主键表的设计如下: 如果id的位置有好几个0
我已经阅读了一些关于将消息从一个线程冒泡到所有其他线程以正常退出的正确方法的来源(每个线程都执行它自己的退出例程)。其中,我喜欢全局原子 bool 值的想法,它可以从任何线程进行标记,所有其他线程检查
本文深入探讨Go语言中的流程控制语法,包括基本的 if-else 条件分支、 for 循环、 switch-case 多条件分支,以及与特定数据类型相关的流程控制,如 for-r
我是 MVC 和 XCode 的新手,在将我对 MVC 的概念理解转化为设计和实现具体类时遇到了困难。我希望就如何构建 Controller 和 View 以获得预期的 UI 获得一些建议。这是针对
如果我尝试在 View 中打开 DeatilFragement,我的应用程序崩溃并收到以下错误: Caused by: java.lang.IllegalStateException: Require
我正在尝试构建我的 iOS 应用程序的界面。一遍又一遍地开始新项目我仍然遇到细节 View 控件的问题(见图)。 在这里我得到了截图: 详细 View 显示当用户触摸 UITableView 行时。您
我在与我正在处理的项目的类(class)中遇到问题。该类是一个接受标签和值的 GUI 组件。这里的想法是,用户可以指定一个标签,然后从任何地方链接一个值(更具体地说,该值的 ToString 方法),
嗯.. 我在我的应用程序中设置了表格 View - 详细 View 。 主视图使用常规代码将数据传递给详细 View - (void)tableView:(UITableView *)tableVie
我有 celery 任务,队列中有 100 个输入数据,需要使用 5 个 worker 来执行。 如何获取哪个工作人员正在执行哪个输入? 每个 worker 执行了多少输入及其状态? 如果任何任务失败
我有一个 .net github 项目,它基本上是一个 Web API 的包装器。在测试项目中,我使用 API key 调用 API。我需要将此 key 保密,如何在 Visual Studio 项目
我遇到一个问题,从 Ag-Grid 导出网格只会导出主网格的详细信息,而不会导出子网格。这是一个显示问题的 plunkr: https://next.plnkr.co/edit/jVcvWDJ1NKP
我在详细 View 中有一个不会消失的额外空间。该 View 来自 NavigationLink,但我已经尝试过使用或不使用 NavigationView。我试图包装它用 NavigationView
几天来,我一直在关注猫效应和 IO。我觉得我对这种效果有一些误解,或者只是我错过了它的重点。 首先——如果IO可以替代Scala的Future,我们如何创建异步IO任务?使用 IO.shift ?使用
如何将标高添加到主视图/详细 View 的详细信息 Pane 中,以在其下方提供阴影,同时定位为部分覆盖工具栏(如下面的底部图片)?我尝试使用 android:elevation="4dp" 但这对我
我试图在我的 UISplitViewController 的细节 View 上设置一个阴影,我希望在 iOS 6 中的主 View 上可见。 在我的细节 View Controller 中: sel
我正在阅读 std::basic_string::reserve(size_type res_arg=0) 上的标准.它是这样说的: void reserve(size_type res_arg=0)
Boost 文档说 Starting with Boost release 1.53, shared_ptr can be used to hold a pointer to a dynamicall
我用 OpenGL 编写了一个简单的 24 位位图加载器。我打开一个位图文件并读取它的像素,然后从中创建一个 RGB 像素数据数组,然后将其传递给 glDrawPixels()。 问题:我需要使图像的
for x in ...循环 就是把每个元素代入变量x,然后执行缩进块的语句。 range()函数,可以生成一个整数序列,再通过list()函数可以转换为list。 比如我们想计算1-10的整数
场景 我有一个 DevExpress XtraGrid。 显示的数据采用主/详细信息格式,点击行开头的“+”可展开该主行的详细信息。 我通过将网格数据源绑定(bind)到包含自己的字典属性(以保存详细
我是一名优秀的程序员,十分优秀!