簡體   English   中英

在C ++中將成員函數轉換為靜態函數

[英]Converting a member function to a static function in 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;
}

編輯后,我的意圖似乎更清楚了。 您可以做的最簡單的事情是在MemoryTester使用靜態成員函數而不是非靜態成員函數。 如果他們需要保持狀態,則必須將該狀態移動為該類的static成員。

如果您的編譯器支持0x lambdas,則可以使用閉包:

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,而不是單例類 ,請使用單個全局對象:

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)以適應同一程序中的其他用途。

如果您正在使用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)。

這里有一些很棒的信息: 替換“新”和“刪除”的教程

如果我理解你的要求,就沒有“約束力”。 一旦分配了內存,就可以告訴編譯器用戶輸入一個類型,在你的情況下是一個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或函數指針,這不是你想要的。

除非您創建一個全局對象。 如果框架采用常規函數指針,那么你就會堅持使用它提供的內容,如果它沒有提供傳統的void * userdata樣式,那么你就會被填充,或者它是全局對象時間。

擁有一個單獨的MemoryTester對象,並具有調用該對象的成員函數的橋接靜態函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM