Я использую shared_ptr и STL широко в проекте, и это приводит к чрезмерно длинным, подверженных ошибкам типов, как shared_ptr < < вектор shared_ptr>> (я являюсь ObjC программист по предпочтению, где длинные имена являются нормой, и все же это слишком много.) Я считаю, что было бы намного яснее, когда я называю это FooListPtr и документируя соглашение об именах, которое «Ptr» означает shared_ptr, а «List» означает вектор shared_ptr.
Для начала, я рекомендую использовать хорошие конструктивные структуры для определения области видимости (например, пространства имен), а также описательные, не сокращенные имена для typedefs. FooListPtr
ужасно короткий, imo. никто не хочет догадываться о том, что означает аббревиатура (или удивляться тому, что Foo является const, shared и т. д.), и никто не хочет изменять свой код просто из-за столкновений с областью.
он также может помочь выбрать префикс для typedefs в ваших библиотеках (а также другие общие категории).
это также плохая идея, чтобы перетащить типы из их заявленной области:
namespace MON {
namespace Diddy {
class Foo;
} /* << Diddy */
/*...*/
typedef Diddy::Foo Diddy_Foo;
} /* << MON */
есть исключения к этому:
- полностью ecapsualted частного типа
- содержимого типа в пределах новый объем
пока мы на нем, using
в следует избегать областей пространства имен и псевдонимов пространства имен - квалифицируйте область действия, если вы хотите свести к минимуму будущую поддержку.
Это легко ввести typedef, но это вызывает головные боли с заголовками. Кажется, у меня есть несколько вариантов определения FooListPtr:
Foo.h. Это переплетает все заголовки и создает серьезные проблемы с построением, поэтому это не стартер.
Это может быть вариант для объявлений, которые действительно зависят от других объявлений. подразумевая, что вам нужно разделить пакеты, или существует общий локализованный интерфейс для подсистем.
FooFwd.h ("forward header"). Это то, что предлагает эффективный C++, основанный на iosfwd.h. Это очень непротиворечиво, но накладные расходы на поддержание в два раза количества заголовков в лучшем случае раздражают.
не беспокойтесь о содержании этого, действительно. это хорошая практика. компилятор использует передовые декларации и typedefs с очень небольшим усилием. это не раздражает, потому что это помогает уменьшить ваши зависимости и помогает обеспечить их правильность и видимость. там действительно больше не нужно поддерживать, поскольку другие файлы относятся к заголовку «типы пакетов».
Common.h (поместить все их вместе в один файл). Это убивает многократное использование, перепутывая множество несвязанных типов. Теперь вы не можете просто подобрать один объект и перенести его в другой проект. Это не стартер.
На основе зависимостей и включений на основе пакетов отличные (идеальные, действительно) - не исключайте этого. вам, очевидно, придется создавать интерфейсы пакетов (или библиотеки), которые хорошо разработаны и структурированы, и представляют связанные классы компонентов. вы делаете ненужную проблему из повторного использования объектов/компонентов. свести к минимуму статические данные библиотеки и позволить фазам связи и полосы выполнять свои задания. еще раз, сохраните свои пакеты в малом и многоразовом, и это не будет проблемой (предполагая, что ваши библиотеки/пакеты хорошо разработаны).
Какая-то причудливая маска #define, которая typedef, если она еще не была наложена. У меня есть пребывающая нелюбовь к препроцессору, потому что я думаю, что это делает его трудным для новых людей, обращали внимание на код, но возможно ....
на самом деле, вы можете объявить ЬурейиЙ в несколько раз тот же области (например, , в двух отдельных заголовках) - это не ошибка.
Объявление typedef в том же объеме с различными базовыми типами является ошибкой. очевидно. вы должны избегать этого, и, к счастью, компилятор этого принуждает.
Чтобы избежать этого, создайте «трансляционную сборку», которая включает в себя мир - компилятор будет отмечать объявления типов с типом, которые не совпадают.
пытается прокрасться с минимальными typedefs и/или форвардами (которые достаточно близки, чтобы освободить при компиляции) не стоит усилий. иногда вам понадобится куча условной поддержки для форвардных объявлений - как только это определено, это легко (библиотеки stl - хороший пример этого - в случае, если вы также отправляете объявление template<typename,typename>class vector;
).
Лучше всего, чтобы все эти объявления были видимыми, чтобы сразу поймать любые ошибки, и вы можете избежать препроцессора в этом случае в качестве бонуса.
Используйте векторный подкласс, а не typedef. Это кажется опасным ...
Подкласс std::vector
часто помечен как «ошибка начинающего». этот контейнер не должен быть подклассом. не прибегайте к плохой практике просто для сокращения времени компиляции/зависимости.если зависимость действительно является то, что значительная, вы, вероятно, следует использовать Pimpl, в любом случае:
// <package>.types.hpp
namespace MON {
class FooListPtr;
}
// FooListPtr.hpp
namespace MON {
class FooListPtr {
/* ... */
private:
shared_ptr< vector< shared_ptr<const Foo> > > d_data;
};
}
Существуют ли лучшие практики здесь? Как они выглядят в реальном коде, когда важны повторяемость, читаемость и согласованность?
В конечном счете, я нашел небольшой подход на основе сжатого пакета, который лучше всего подходит для повторного использования, для сокращения времени компиляции и минимизации зависимости.
Могу ли я спросить, почему этот вопрос является вики-сообществом? –
@ Konrad, если бы были другие предложения, я предлагал добавить их в список, чтобы упростить для последующих читателей различные варианты, отличные от ответов по их достоинствам. Возможно, вики сообщества используются по-разному? –
И после большего исследования я заново открыл то, что обнаружил в прошлый раз, когда я щелкнул вики сообщества, а это значит, что я не хотел этого делать ... Надеюсь, на этот раз я выучил свой урок. –