c – 避免嵌入式编程中的全局变量

前端之家收集整理的这篇文章主要介绍了c – 避免嵌入式编程中的全局变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在我所涉及的嵌入式编程类型中,运行代码的确定性和透明性受到高度重视.我透露的意思是,例如,能够查看内存的任意部分并知道存储的变量.因此,正如我确信嵌入式程序员所期望的那样,如果可能的话,应该避免使用new,如果无法避免,则仅限于初始化.

我理解这种需要,但不同意我的同事这样做的方式,也不知道更好的选择.

我们拥有几个全局结构数组和一些全局类.有一个用于互斥锁的结构数组,一个用于信号量,一个用于消息队列(这些是在main中初始化的).对于每个运行的线程,拥有它的类是全局变量.

我遇到的最大问题是单元测试.当我想测试的类#includes全局变量时,我如何插入模拟对象?

这是伪代码的情况:

foo.h中

#include "Task.h"
class Foo : Task {
public:
  Foo(int n);
  ~Foo();
  doStuff();
private:
  // copy and assignment operators here
}

bar.h

#include <pthread.h>
#include "Task.h"

enum threadIndex { THREAD1 THREAD2 NUM_THREADS };
struct tThreadConfig {
  char      *name,Task      *taskptr,pthread_t  threadId,...
};
void startTasks();

bar.cpp

#include "Foo.h"

Foo foo1(42);
Foo foo2(1337);
Task task(7331);

tThreadConfig threadConfig[NUM_THREADS] = {
  { "Foo 1",&foo1,... },{ "Foo 2",&foo2,{ "Task",&task,... }
};

void FSW_taskStart() {
    for (int i = 0; i < NUMBER_OF_TASKS; i++) {
        threadConfig[i].taskptr->createThread(  );
    }
}

如果我想要更多或更少的任务怎么办? foo1的构造函数中有一组不同的参数?我想我必须有一个单独的bar.h和bar.cpp,这似乎比必要的工作要多得多.

解决方法

如果你想先对这些代码进行单元测试,我建议你阅读 Working Effectively With Legacy Code另见 this.

基本上使用链接器插入模拟/伪对象和函数应该是最后的手段,但仍然是完全有效的.

但是,您也可以使用控制反转,如果没有框架,这可能会对客户端代码产生一些责任.但它确实有助于测试.例如,测试FSW_taskStart()

tThreadConfig threadConfig[NUM_THREADS] = {
  { "Foo 1",%foo1,%foo2,%task,... }
};

void FSW_taskStart(tThreadConfig configs[],size_t len) {
    for (int i = 0; i < len; i++) {
        configs[i].taskptr->createThread(  );
    }
}

void FSW_taskStart() {
    FSW_taskStart(tThreadConfig,NUM_THREADS);
}

void testFSW_taskStart() {
    MockTask foo1,foo2,foo3;
    tThreadConfig mocks[3] = {
          { "Foo 1",&foo3,... }
        };
    FSW_taskStart(mocks,3);
    assert(foo1.started);
    assert(foo2.started);
    assert(foo3.started);
}

现在你可以将你的线程的模拟版本传递给’FSW_taskStart’,以确保该函数确实根据需要启动线程.不幸的是,您必须依赖原始FSW_taskStart传递正确参数的事实,但您现在正在测试更多代码.

猜你在找的C&C++相关文章