2011-10-09 27 views
0

有沒有設定一個虛函數表指針使用malloc分配的對象的任何編譯器無關語法和優雅的方式?在虛函數表的指針和malloc的

我不能直接使用new,因爲我需要能夠根據需要控制內存釋放流,這需要使用void ptrs來保存內存管理器中的內存位置,直到有足夠的時間釋放爲止。

class AbstractData 
{ 
public: 
    AbstractData() {} 
    virtual ~AbstractData() {} 

protected: 
    virtual void SetData(int NewData) =0; 
    virtual int GetData() const =0; 
}; 

class ConcreteData : public AbstractData 
{ 
protected: 
    int Data; 

public: 
    ConcreteData() {} 
    ~ConcreteData() {} 

    void SetData(int NewData); 
    int GetData() const; 

}; 

void ConcreteData::SetData(int NewData) {Data=NewData;} 

int ConcreteData::GetData() const 
{return Data;} 

int main(int argc, char* argv[]) 
{ 
    int OBJ_NUMBER = 4; 
    ConcreteData* Test = (ConcreteData*)malloc(OBJ_NUMBER*sizeof(ConcreteData)); 

    if (!Test) 
     return -1;   

    for (int x = 0; x < OBJ_NUMBER; x++) 
     Test[x] = ConcreteData(); 

    Test[0]->GetData(); //Constructor was never called, vptr never initialized, crash 

    free(Test); 
    Test = NULL; 
} 

我希望本地副本將有一個初始化虛函數表的指針,但可惜事實並非如此。 我知道你可以做一個編譯器相關的間接引用到的vptr的偏移,如果你知道它在哪裏,但這種方法是依賴於編譯器和不雅在許多分配使用。例如用MSVC工程++ 8.0

int main(int argc, char* argv[]) 
{ 
    int OBJ_NUMBER = 4; 
    ConcreteData* Test = (ConcreteData*)malloc(OBJ_NUMBER*sizeof(ConcreteData)); 

    if (!Test) 
     return -1;   

    ConcreteData StealVPtr(); 

    int* VPtr = *(int**)StealVPtr; 

    for (int x = 0; x < OBJ_NUMBER; x++) 
     *(int**)Test[x] = VPtr; 

    Test[0]->GetData(); //VPtr initialized in compiler dependent way 

    free(Test); 
    Test = NULL; 
} 

另外,放置新的可以使用,但再次,它看起來語法不雅,並可能導致陣列抵消類型的問題,析構函數時,增加了陣列中的PTR前面數。

int main(int argc, char* argv[]) 
{ 
    int OBJ_NUMBER = 4; 
    ConcreteData* Test = (ConcreteData*)malloc(OBJ_NUMBER*sizeof(ConcreteData)); 

    if (!Test) 
     return -1;   

    for (int x = 0; x < OBJ_NUMBER; x++) 
    { 
     if (!(ConcreteData* PlcTest = new(Test[x]) ConcreteData())) 
     { 
      free(Test); 
      Test = NULL; 
      return -1; 
     } 
    } 

    PlcTest[0]->GetData(); //Constructor was invoked and VPtr was initialized 

    for (int x = OBJ_NUMBER-1; x >= 0; x--) 
     PlcTest[x].~ConcreteData(); 

    PlcTest = NULL; 

    free(Test); 
    Test = NULL; 
} 

這些真的是使用malloc初始化對象的VTable ptr/call構造函數的唯一方法嗎?

+3

新聽起來就像這裏一個不錯的選擇。也許你需要再次看看導致你採取這種策略的原因。 –

+1

必須被說的最好的和有禮貌的方式「WTF?!?」。注意將來使用! –

+0

標記爲'c'? C有沒有新的或類,或公開,或虛擬,或保護,或構造函數和析構函數的概念;它不需要爲'malloc'的返回值強制轉換,...​​,... – pmg

回答

0

你可能不知道,你可以覆蓋全球newdelete。注意,您還需要重寫new[]delete[]是完整的

下面的例子:

void * operator new(size_t size) 
{ 
    return super_malloc(size); 
}