C++, добавление временных объектов в список без динамического выделения памяти

Я пишу код для встроенной платформы, поэтому не могу использовать обычный оператор new.

Теперь я хочу добавить произвольные объекты в список, вот так.

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;
}

3 ответа

  1. Если вы используете C++11, вы можете написать функцию пересылки, чтобы сделать работу за вас:

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

    Затем вы добавите объект в свой список, например so:

    tp.add(make<Derived>("John"));
    
  2. Мое предпочтительное решение теперь-следующий макрос:

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

    теперь я могу добавить новый объект с помощью этого кода:

    tp.add(m(Derived("Isabella")));
    
  3. Вы не можете просто переопределить new для использования myalloc ? Если вы не хотите делать это глобально, вы, конечно, можете сделать это для базы