在C ++中将成员函数转换为静态函数

时间:2011-05-16 20:29:53

标签: c++

我正在编写一个内存测试框架,在其中我用自己的内存替换动态内存分配函数(例如,malloc,realloc,free等)。但是,系统需要静态函数(我不能改变它)。

我有一个MemoryTester类,它记录内存调用,我想绑定其内存分配函数的成员函数实现。这可能用C ++吗?

编辑:

这是一些突出我正在尝试做的代码:

typedef void*(allocateFuncPtr) (uint8_t);
typedef void (freeFuncPtr) (void*);

void setAllocateFunction(allocateFuncPtr) {...}
void setFreeFunction(freeFuncPtr) {...}


class MemoryTester
{
    void *malloc(uint8_t size);
    void free(void *ptr);
}

int main()
{
    MemoryTester *tester = new MemoryTester();

    //want to set allocate and free functions to those in tester
    setAllocateFunction( tester->getAllocateFunction() );
    setFreeFunction( tester->getFreeFunction() );

    return 0;
}

6 个答案:

答案 0 :(得分:3)

编辑后,意图对我来说更清晰。您可以做的最简单的事情是在MemoryTester中使用静态成员函数而不是非静态成员函数。如果他们需要保持状态,那么该州必须被移动为该班级的static成员。

答案 1 :(得分:3)

如果你的编译器支持0x lambda,你可以使用闭包:

int main() {
  MemoryTester tester;  // If no need for dynamic allocation, don't use it.

  setAllocateFunction([&tester](uint8_t size) { return tester.malloc(size); });
  setFreeFunction([&tester](void *p) { tester.free(p); });

  return 0;
}

您的MemoryTester类无需更改,也无需更改库SetAllocateFunction& setFreeFunction属于。


如果没有lambda,而不是a singleton class,请使用单个全局对象:

struct MemoryTester {
  void* malloc(uint8_t size);  // Neither are static.
  void free(void *p);
};

MemoryTester tester_a;
void* tester_a_malloc(uint8_t size) { return tester_a.malloc(size); }
void tester_a_free(void *p) { return tester_a.free(p); }

int main() {
  setAllocateFunction(&tester_a_malloc);
  setFreeFunction(&tester_a_free);
}

这里的优点是整个MemoryTester类因为一个特殊需要而没有受到限制。您可以根据需要创建更多功能(例如tester_b_malloc / free),以适应同一程序中的其他用途。

答案 2 :(得分:1)

如果您正在使用GCC,那么您可以让链接器使用--wrap选项(或-Wl, - wrap,malloc)为您包装该函数。

然后你可以拦截对malloc的调用,因为对该函数的所有调用都将被重定向到__wrap_malloc。你可以使用名称__real_malloc来调用真实的(原始c-lib)malloc函数,或者你可以替换你自己的替换(如果没有调用__real_malloc,那么链接器可能能够删除原来的c- lib malloc all-together)。

void *__wrap_malloc (size_t c)
{
  printf ("malloc called with %zu\n", c);
  return __real_malloc (c);
}

FWIW,您可以替换全局的new和delete操作,然后您可以只使用自己的内存系统(即使您使用第三方编译库中的代码,只要它们没有重载全局new和delete) )。

以下是一些很棒的信息:Tutorial of Replacing "new" and "delete"

答案 3 :(得分:0)

如果我理解你的要求,那就没有“约束力”了。一旦分配了内存,就可以告诉编译器用户输入一个类型,在你的情况下是一个reinterpret_cast。例如,在你的分配函数中:

unsigned char* raw_memory = allocation( std::size_t );
MyFinalType* object = reinterpret_cast<MyFinalType*>(raw_memory); // tells the compiler to take this memory as a MyFinalType.

然后你返回你的最终类型。

要知道要使用哪种类型,您肯定希望使用模板。

不要忘记C ++是一种静态类型语言:您不能将函数绑定到对象类型。好的,你可以,但是,你必须使用std :: function或函数指针,这不是你想要的。

答案 4 :(得分:0)

除非您创建全局对象。如果框架采用常规函数指针,那么你就会遇到它提供的内容,如果它没有提供传统的void * userdata样式,那么你就会被填充,或者它是全局对象时间。

答案 5 :(得分:-2)

拥有一个单独的MemoryTester对象,并具有调用该对象的成员函数的桥接静态函数。