2015-05-09 6 views
6

У меня есть иерархия операций и (общих) информационных классов, где интуитивно кажется, что нет необходимости в политике времени выполнения, и все же я не могу найти решение без него.CRTP с циклической зависимостью

Для этого вопроса предположим, что существует двухуровневая иерархия. Существует базовая операция и производная операция. Объектам с одинакового уровня иерархии может потребоваться обмен информацией между ними (что означает, что объектам базового режима необходимо обмениваться базовой информацией, а производным операционным объектам необходимо обмениваться производной информацией, но базовым операционным объектам никогда не нужно делиться полученной информацией или пороками Versa).

Так начинается так:

// Shared between base operation objects 
class base_info 
{ 

}; 

// Shared between derived operation objects 
class derived_info : 
    public base_info 
{ 

}; 

Учитывая, что нет времени выполнения, вопрос о том, какие операции объекты долю которых информационные объекты, есть также следующие:

template<class Info> 
class base_op 
{ 
    std::shared_ptr<Info> m_info; 
}; 

class derived_op : 
    public base_op<derived_info> 
{ 

}; 

Остальная кода всегда создает base_op с base_information, и поэтому здесь не требуется полиморфизм времени выполнения.

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

// Shared between base operation objects 
class base_info : 
    private std::enable_shared_from_this<base_info> 
{ 
    void do_something_spawning_new_ops(); 
}; 

... 

Сейчас проблема заключается в том, как реализовать do_something_spawning_new_ops. С выполнения polymporphism, это не так уж сложно:

class base_info : 
    private std::enable_shared_from_this<base_info> 
{ 
    void do_something_spawning_new_ops() 
    { 
     // Need a new op. 
     get_op_shared_ptr(); 
    } 

    virtual std::shared_ptr<base_op> get_op_shared_ptr() 
    { 
     // use shared_from_this, create a base_op object using it. 
    } 
}; 

class derived_info : 
    public base_info 
{ 
    virtual std::shared_ptr<base_op> get_op_shared_ptr() 
    { 
     // use shared_from_this + std::*_pointer_cast, 
     // create a derived_op object 
    }  
}; 

, но дело в том, чтобы избежать выполнения полиморфизм, так как по конструкции, все может быть известно в конкретизации. Так возвращаясь к началу поста, было бы неплохо иметь что-то вроде этого:

template<class Op> 
class base_info 
{ 

}; 

class derived_info : 
    public base_info<derived_op> 
{ 

}; 

с CRTP рода штуковина (хотя и без вывода), где ор говорит, что он держит информацию о создании объектов этого типа. Но теперь это вызывает циклическую проблему для создания base_op. Он каким-то образом должен быть создан каким-то информационным типом, который сам создается экземпляром своего типа и т. Д. И т. Д. Я не знаю, как остановить этот тип цикла.

Редактировать

По предложению PANTA RHEI, в here есть код, я стремился.

+2

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

+0

Циклические зависимости могут быть решены путем задержки создания экземпляра шаблона. Это можно сделать, добавив еще один слой. – rpress

+0

Вы оставляете много неизвестных/неопределенных вещей в своем вопросе. Предоставьте [MCVE] (http://stackoverflow.com/help/mcve) или, по крайней мере, ссылку на одну из них, например. используя онлайн-IDE, например [Ideone] (http://ideone.com/). –

ответ

3

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

int main() 
{ 
    derived_op d; 
    base_op<base_info<derived_info> > b; 
} 
Смежные вопросы