2015-04-01 2 views
0

Существует ли стандартный шаблон проектирования, с помощью которого я могу вернуть полиморфный тип из процедуры, не требуя также динамического выделения памяти для объекта в рамках процедуры?Возвратите полиморфный тип без динамического распределения памяти?

Или полиморфизм и динамическое распределение памяти обязательно идут рука об руку на практике?

Я надеюсь на совместимое с C++ 03 решение, но если есть C++ 11, то мне также интересно это увидеть.

+3

Вы должны быть более конкретными. Если вы точно знаете тип, вы можете просто вернуть его по значению. Если вы вернете указатель, это необязательно должно быть связано с динамически выделенным объектом. –

+0

I.e. пул объектов. –

+1

@NeilKirk: Кто «ты» в своем вопросе? Процедура знает динамический тип (думаю: переопределен производными классами), но, очевидно, вызывающий не делает (это не в сигнатуре функции), иначе полиморфизм будет бессмысленным. – Mehrdad

ответ

0

Object Pool

Действительно это для работы, сократить ассигнования; он кажется применимым в вашем сценарии, однако, предполагая, что у вас есть ограничение на количество экземпляров объекта. Приведенный ниже код иллюстрирует эту идею. Для этого требуется априорное знание того, какие типы задействованы (поскольку вам необходимо выделить необходимые буферы объектов). Также удаление (возвращение типа в пул) требует осторожности и знаний о типе. Это можно сделать с помощью вызова виртуальной функции.

template< typename Type > 
struct TypePool 
{ 
    static TypePool& GetInstance(){ return pool; } 

    Type& GetPooledObject() 
    { 
     return arr[0]; // do some real tracking here 
    } 

    private: 
    static TypePool<Type> pool; 
    Type arr[10]; 
}; 

struct A{ }; 
struct B : public A { }; 
struct C : public A { }; 

// The catch to this design... 
TypePool<A> TypePool<A>::pool; 
TypePool<B> TypePool<B>::pool; 
TypePool<C> TypePool<C>::pool; 

struct ObjectFactory 
{ 
    // Actual function you would call to construct the object 
    // ObjectFactory::GetType<A> or GetType<B> 
    template< typename Type > 
    static A& GetType() 
    { 
     return TypePool<A>::GetInstance().GetPooledObject(); 
    } 
}; 


int main(int argc, char* r[]) 
{ 
    A& object = ObjectFactory::GetType<C>(); 
} 
+0

Разве это не требовало бы, чтобы вызывающий передал вызывающему пользователю указатель на пул объектов правильного типа? Или вы говорите, что мне нужно локальное хранилище потоков (только для C++ 11)? Поскольку сохранение указателя на пул внутри каждого объекта нежелательно ... – Mehrdad

+0

Пул статический (для каждого типа, посмотрите на элемент 'static пул пула TypePool '), поэтому во время компиляции определяется, какой пул использовать. Каждый тип может легко ссылаться на свой собственный пул через 'TypePool < MyType > :: GetInstance' и поэтому возвращать себя. –

+2

Пул объектов - одно из немногих мест, где я был бы в порядке с синглом. –

Смежные вопросы