2016-11-09 59 views
0

我正在爲嵌入式平臺編寫代碼,因此我無法使用普通的new運算符。C++,將臨時對象添加到列表中,沒有動態內存分配

現在我想添加任意對象到列表中,就像這樣。

tp.add(DerivedA("David")); 
tp.add(DerivedB("Max")); 
tp.add(DerivedC("Thomas")); 

對於代碼重複的原因,我不想寫是這樣的:

DerivedA david("David"); 
tp.add(david); 
... 

解決方案,但不是很漂亮的風格會是這樣:

tp.add(new (myalloc(sizeof(DerivedB))) DerivedB("John")); 
// using placement-new works 

現在我試着添加一個臨時對象,通過指針傳遞:

tp.add(&DerivedA("David")); 

理論上這可以工作,但編譯器抱怨(有充分的理由)將指針傳遞給臨時對象(-fpermissive)。

有沒有乾淨的做我想做的事情?

這是一個完整的例子:

#include <iostream> 

using namespace std; 

class Base // base class 
{ 
public: 
    Base(); 
    int size; 
    char name[100]; 
}; 

class Derived:public Base 
{ 
public: 
    Derived(char* name); 
}; 

class ThirdParty 
{ 
public: 
    void add(Base* obj); 
    void addTemp(Base* tempObj); 
    Base* list[10]; 
    int index; 
}; 


void* myalloc(int size){ 
    void* p; 
    // ... 
    // allocate memory in a static memory pool 
    // ... 
    return p; 
} 

void memcpy(void* to, void* from, int size){ 

} 


int main() 
{ 
    ThirdParty tp; 

    // The ugly style: 
    tp.add(new (myalloc(sizeof(Derived))) Derived("John")); // using placement-new works 

    // The beauty style (compiler complains here): 
    tp.addTemp(&Derived("David")); // create temporary object here, which is copied and added to the list 
    tp.addTemp(&Derived("Max")); 
    tp.addTemp(&Derived("Thomas")); 

    return 0; 
} 


Base::Base() 
{ 
    size = sizeof(Base); 
} 

Derived::Derived(char *name) 
{ 
    size = sizeof(Derived); // make size of this object available for a base-pointer 
} 

void ThirdParty::add(Base *obj) 
{ 
    list[index++] = obj; 
} 

void ThirdParty::addTemp(Base* tempObj) 
{ 
    Base* newObj = (Base*) myalloc(tempObj->size); // let third party allocate memory 
    memcpy(newObj, tempObj, tempObj->size); // copy the temporary object 
    list[index++] = newObj; 
} 
+0

有點更美麗可能是這個宏:「#define m(x)new(myalloc(sizeof(x)))x」 –

回答

0

我首選的方案是現在下面的宏:

#define m(x) new (myalloc(sizeof(x))) x 

現在我可以添加一個新的對象與此代碼:

tp.add(m(Derived("Isabella"))); 
0

如果使用C++ 11,你可以寫一個轉發功能做的工作適合你:

template <typename T, typename... Args> 
T* make (Args&&... args) { 
    return new (myalloc(sizeof(T))) T { std::forward<Args>(args)... }; 
} 

你會再加入對象到您的列表,像這樣:

tp.add(make<Derived>("John")); 
+0

謝謝,似乎是一個可能的解決方案。但是我認爲自動完成對構造函數不起作用了! –

+0

我剛剛測試了你的方法,並且代碼完成(建議)不再像QtCreator所預期的那樣工作。 –

+0

我認爲丟失代碼完成遠比宏駭客更可取,但也許這只是我。 – TartanLlama

0

你能不能只覆蓋新的使用myalloc?如果你不想在全球範圍內做到這一點,你當然可以做到這一點基地