Переменная typedef внутри того же класса. Это хорошая практика? - PullRequest
1 голос
/ 22 декабря 2010

Сначала я пытался определить класс шаблона и попал в статью " gotw 79 ".И я не хотел создавать другой класс, поэтому я сделал следующее.В основном typedef'ing внутри того же класса.Это работает очевидно.но разве это хорошая практика?

template <typename T,typename L>
class MyClass{
     typedef std::tr1::shared_ptr<MyClass<T,L> > shrdPtr;
}

Спасибо.

Ответы [ 5 ]

4 голосов
/ 22 декабря 2010

Ну, я не большой поклонник этого, если вы не разрабатываете MyClass для специального использования только в объектах shared_ptr, и в этот момент я бы настаивал на том, чтобы требование выполнялось.

Это немногоСмешно помещать typedefs для каждого несвязанного экземпляра шаблона, который вы можете использовать с данным объектом.Тот факт, что вы можете поместить MyClass в shared_ptr, не является хорошей причиной для его определения там.Вы собираетесь поместить typedefs для std :: vector, map, list, unordered_map, set, deque, .... и т. Д. И т. Д. И т. Д.

Но если MyClass расширяет shared_from_this и имеет частные / защищенные конструкторытак что он может быть создан ТОЛЬКО ТОЛЬКО и сразу же назначен для shared_ptr, тогда ... конечно ... это часть интерфейса.

Если вы пытаетесь избежать необходимости вводить длинные списки параметров для создания экземпляраshared_ptr для шаблонного типа с большим количеством параметров, тогда лучшая ставка - это служебный объект EXTERNAL, как показано в цитированной вами статье:

template < typename T >
struct instantiate_shared_ptr { typedef shared_ptr<T> type; };

template < typename after typename > struct my_complex_template {};
typedef my_complex_template<some parameters> mct_1;
typedef instantiate_shared_ptr<mct_1>::type mct_1_sp;
1 голос
/ 22 декабря 2010

Да, особенно если имя MyClass_sp указано в коде клиента.

0 голосов
/ 23 декабря 2010

Это хорошо, ИМО.
Я использовал это много.
Если я хочу использовать контейнер, элемент которого является типом моего шаблона, я его определяю.
Например,

template <typename T>  
class MyClass {  
private:  
    typedef std::list<T> SomeContainerType;  
    typedef SomeContainerType::iterator IteratorType;  

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

0 голосов
/ 22 декабря 2010

Лучшим решением для определения типа умного указателя является использование их после определения класса в заголовке:

namespace N
{
    class A
    {
    };

    typedef std::tr1::shared_ptr<A> APtr;
}

Это позволяет сохранить определение умного указателя рядом с определением класса, не давая вам (и всем разработчикам, использующим ваше определение).код) от необходимости писать код вроде A::APtr a(new A) (который выглядит просто странно).

РЕДАКТИРОВАТЬ: Так как он занимается с шаблоном класса:

namespace N
{
    template<class T, class L>
    class A
    {
    };

    template<class T, class L>
    struct A_Instantiator
    {
        typedef std::tr1::shared_ptr<A<T, L> > APtr;
    };
}
0 голосов
/ 22 декабря 2010

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

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

...