Wewnętrzny typ W C++ - dobry czy zły styl?

Coś, co ostatnio często robię, to deklarowanie typedefów związanych z konkretną klasą wewnątrz tej klasy, tj.

class Lorem
{
    typedef boost::shared_ptr<Lorem> ptr;
    typedef std::vector<Lorem::ptr>  vector;

//
// ...
//
};

Typy te są następnie używane gdzie indziej w kodzie:

Lorem::vector lorems;
Lorem::ptr    lorem( new Lorem() );

lorems.push_back( lorem );

Powody, dla których to lubię:

  • redukuje szum wprowadzany przez szablony klas, std::vector<Lorem> staje się Lorem::vector, itd.
  • W tym celu należy skontaktować się z Działem Obsługi Klienta pod numerem telefonu + 48 22 222 50 00, a następnie skontaktować się z Działem Obsługi Klienta pod numerem telefonu + 48 22 222 50 00. wektor.
  • pozwala na zmianę implementacji - tzn. jeśli lorem musi zostać zmieniony, aby być liczonym w sposób intruzywny (poprzez boost::intrusive_ptr) na późniejszym etapie, to miałoby to minimalny wpływ na kod.
  • myślę, że wygląda "ładniej" i jest prawdopodobnie łatwiejsza do odczytania.

Powody, dla których mi się to nie podoba:

  • czasami występują problemy z zależnościami - jeśli chcesz osadzić, powiedzmy, Lorem::vector w innej klasie, ale tylko potrzebujesz (lub chcesz) forward declare Lorem (w przeciwieństwie do wprowadzania zależności od jego pliku nagłówkowego) w końcu musisz użyć jawnych typów (np. boost::shared_ptr<Lorem> zamiast Lorem::ptr), co jest trochę niespójne.
  • [16]}to może nie być zbyt powszechne, a zatem trudniejsze do zrozumienia?

Staram się być obiektywny z moim stylu kodowania, więc byłoby dobrze, aby uzyskać kilka innych opinii na ten temat, więc mogę przeanalizować moje myślenie trochę.

Author: Will Baker, 2009-04-17

9 answers

Uważam, że jest to świetny styl i sam go używam. Zawsze najlepiej jest ograniczyć zakres nazw tak bardzo, jak to możliwe, a użycie klas jest najlepszym sposobem, aby to zrobić w C++. Na przykład, Biblioteka Standardowa C++ intensywnie wykorzystuje typedefs w klasach.

 135
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 08:31:03

Służy jako oświadczenie woli - w powyższym przykładzie Klasa Lorem jest przeznaczony do liczenia odniesienia via boost:: shared_ptr i przechowywane w wektor.

To jest dokładnie to, co robi , a nie .

Jeśli widzę 'Foo:: Ptr' w kodzie, absolutnie nie mam pojęcia, czy to shared_ptr czy Foo* (STL ma ::pointer typedefs, które są T*, pamiętaj) czy cokolwiek. Esp. jeśli jest to wskaźnik współdzielony, w ogóle nie podaję typedef, ale zachowaj shared_ptr używa jawnie w kodzie.

Właściwie, rzadko używam typedefów poza Metaprogramowaniem szablonów.

STL robi tego typu rzeczy cały czas

Konstrukcja STL z pojęciami zdefiniowanymi w kategoriach funkcji Członkowskich i zagnieżdżonych typów jest historycznym zaułkiem, nowoczesne biblioteki szablonów używają wolnych funkcji i klas cech (por. Boost.Graf), ponieważ nie wykluczają one wbudowanych typów z modelowania koncepcji oraz dlatego, że sprawia łatwiejsze dostosowanie typów, które nie zostały zaprojektowane z myślą o pojęciach bibliotek szablonów.

Nie używaj STL jako powodu do popełniania tych samych błędów.

 10
Author: Marc Mutz - mmutz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-12 14:10:29

Typedefs to te, którepolicy based design and traits zostały zbudowane w C++, więc moc generycznego programowania w C++ wynika z samych typedefów.

 9
Author: Özgür,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 08:44:36

Typdefy są zdecydowanie dobrym stylem. I wszystkie twoje "powody, które lubię" są dobre i poprawne.

O problemach z tym. Deklaracja nie jest świętym graalem. Możesz po prostu zaprojektować swój kod, aby uniknąć wielopoziomowych zależności.

Możesz przenieść typedef poza klasę, ale Class:: ptr jest o wiele ładniejsza niż ClassPtr, że tego nie robię. Jest tak jak w przypadku przestrzeni nazw, jak dla mnie-rzeczy pozostają połączone w ramach zakresu.

Sometimes I did

Trait<Loren>::ptr
Trait<Loren>::collection
Trait<Loren>::map

I może być domyślna dla wszystkich klas domenowych i z pewną specjalizacją dla niektórych.

 7
Author: Mykola Golubyev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 08:35:36

STL robi tego typu rzeczy cały czas - typedefs są częścią interfejsu dla wielu klas w STL.

reference
iterator
size_type
value_type
etc...

Są typedefami, które są częścią interfejsu dla różnych klas szablonów stl.

 3
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 08:36:43

Kolejny głos za dobrym pomysłem. Zacząłem to robić, pisząc symulację, która musiała być efektywna, zarówno w czasie, jak i przestrzeni. Wszystkie typy wartości miały typedef Ptr, który zaczynał się jako wskaźnik współdzielony boost. Następnie zrobiłem profilowanie i zmieniłem niektóre z nich na natrętny wskaźnik boost bez konieczności zmiany żadnego kodu, w którym te obiekty były używane.

Zauważ, że działa to tylko wtedy, gdy wiesz, gdzie będą używane klasy, i że wszystkie zastosowania mają te same wymagania. Nie używałbym tego na przykład w kodzie biblioteki, ponieważ nie można znać podczas pisania biblioteki kontekstu, w jakim będzie ona używana.

 3
Author: KeithB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 14:13:54

Zalecam przeniesienie tych wpisów poza klasę. W ten sposób usuwa się bezpośrednią zależność od współdzielonych klas wskaźnika i wektora i można je dołączać tylko wtedy, gdy jest to potrzebne. Chyba, że używasz tych typów w swojej klasie implementacji, uważam, że nie powinny one być typami wewnętrznymi.

Powody, dla których to lubisz, są nadal dopasowane, ponieważ są rozwiązywane przez aliasing typu poprzez typedef, a nie przez deklarowanie ich wewnątrz twojej klasy.

 2
Author: Cătălin Pitiș,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 08:28:24

Obecnie pracuję nad kodem, który intensywnie używa tego typu typedefów. Jak na razie jest dobrze.

Ale zauważyłem, że są dość często iteracyjne typy, definicje są podzielone na kilka klas i nigdy nie wiadomo, z jakim typem masz do czynienia. Moim zadaniem jest podsumowanie wielkości niektórych złożonych struktur danych ukrytych za tymi typedefami - więc nie mogę polegać na istniejących interfejsach. W połączeniu z trzema do sześciu poziomów zagnieżdżonych przestrzeni nazw, a następnie staje się mylące.

Więc przed ich użyciem należy rozważyć kilka punktów

  • czy ktoś jeszcze potrzebuje tych wpisów? Czy klasa jest często używana przez inne klasy?
  • czy skracam użycie czy ukrywam klasę? (W przypadku ukrycia można również pomyśleć o interfejsach.)
  • Czy inni ludzie pracują z kodem? Jak oni to robią? Czy będą myśleć, że to łatwiejsze, czy będą zdezorientowani?
 1
Author: Bodo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-18 08:28:57

Kiedy typedef jest używany tylko w samej klasie (tzn. jest zadeklarowany jako prywatny) myślę, że to dobry pomysł. Jednak z dokładnie tych powodów, które podajesz, nie użyłbym go, gdyby typedef musiał być znany poza klasą. W takim razie polecam przenieść ich poza klasę.

 0
Author: Stefan Rådström,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-17 08:31:08