Вложенные классы
У классов, вложенных в классы, есть несколько побочных эффектов, которые я обычно считаю недостатками (если не чистыми антипаттернами).
Давайте представим следующий код:
class A
{
public :
class B { /* etc. */ } ;
// etc.
} ;
Или даже:
class A
{
public :
class B ;
// etc.
} ;
class A::B
{
public :
// etc.
} ;
So:
- Привилегированный доступ: A::B имеет привилегированный доступ ко всем элементам A (методам, переменным, символам и т. д.), что ослабляет инкапсуляцию.
- Область A является кандидатом для поиска символов: код внутри B увидит все символы из A как возможные кандидаты для поиска символов, что может запутать код.
- forward-declaration: невозможно выполнить forward-declare A::B без полного объявления A
- Расширяемость: невозможно добавить еще один класс A::C, если вы не являетесь владельцем класса A.
- Многословие кода: помещение классов в классы только увеличивает размер заголовков. Вы все еще можете разделить это на несколько объявлений, но нет возможности использовать псевдонимы, импорт или использование, подобные пространству имен.
В заключение, за исключением исключений (например, вложенный класс является интимной частью вложенного класса... И даже тогда...), я не вижу смысла во вложенных классах в обычном коде, поскольку недостатки значительно перевешивают предполагаемые преимущества. .
Кроме того, это пахнет неуклюжей попыткой имитировать пространство имен без использования пространств имен C++.
С другой стороны, вы изолируете этот код и, если он частный, делает его непригодным для использования, но из внешнего класса...
Вложенные перечисления
Плюсы: Все.
Кон: Ничего.
Дело в том, что элементы перечисления будут загрязнять глобальную область видимости:
// collision
enum Value { empty = 7, undefined, defined } ;
enum Glass { empty = 42, half, full } ;
// empty is from Value or Glass?
Только поместив каждое перечисление в другое пространство имен/класс, вы сможете избежать этого столкновения:
namespace Value { enum type { empty = 7, undefined, defined } ; }
namespace Glass { enum type { empty = 42, half, full } ; }
// Value::type e = Value::empty ;
// Glass::type f = Glass::empty ;
Обратите внимание, что C++0x определил перечисление класса:
enum class Value { empty, undefined, defined } ;
enum class Glass { empty, half, full } ;
// Value e = Value::empty ;
// Glass f = Glass::empty ;
именно для таких задач.
person
paercebal
schedule
19.10.2008