У меня иногда есть классы с частными статическими элементами данных. В настоящее время я обсуждаю, следует ли заменить их статическими переменными в неназванном пространстве имен в файле реализации. Другие, которые не могут использовать эти переменные в встроенных методах, есть ли другие недостатки? Преимущество, которое я вижу, это то, что полностью скрывает их от пользователей этого класса.статические данные класса против анонимных пространств имен в C++
ответ
Я не уверен, что это преимущество стоит для удобства чтения. Я вообще считаю что-то частное, чтобы быть «достаточно скрытым».
Это не только скрывает их от пользователей класса, но и скрывает их от вас! Если эти переменные являются частью класса, они должны быть связаны с классом каким-то образом.
В зависимости от того, что вы собираетесь делать с ними, вы могли бы рассмотреть возможность их статические переменные внутри статические функций-членов:
// header file
class A {
public:
static void func();
};
// cpp file
void A :: func() {
static int avar = 0;
// do something with avar
}
1) Существует недостаток в виде дополнительного ограничения на двоичных организациях , В презентации на конференции C++ в 1990-х годах Уолтер Брайт сообщал о достижении значительного повышения производительности путем организации своего кода, так что функции, которые называли друг друга, находились в одном модуле компиляции. Например, если во время выполнения Class1 :: method1 сделал гораздо больше вызовов методам Class2, чем другим методам Class1 ::, то определение Class1 :: method1 в class2.cpp означало, что Class1 :: method1 будет на той же кодовой странице, что и методы он звонил и, следовательно, с меньшей вероятностью задерживался ошибкой страницы. Такой рефакторинг легче выполнять с помощью статики класса, чем с статикой файлов.
2) Одним из аргументов против, представляющим ключевое слово namespace, было «Вы можете сделать то же самое с классом», и вы увидите, что класс и структура используются как пространство имен бедных людей в источниках из pre - эпоха пространства имен. Убедительный контр-аргумент состоял в том, что пространства имен снова открываются, и любая функция в любом месте может сделать себя частью пространства имен или получить доступ к внешнему пространству имен, тогда были вещи, которые вы могли бы сделать с пространством имен, которое вы могли бы не делать с классом , Это имеет отношение к вашему вопросу, потому что это говорит о том, что языковой комитет думал о пространстве имен как очень похож на класс; это уменьшает вероятность того, что существует некоторая тонкая лингвистическая ловушка при использовании анонимного пространства имен вместо статического класса.
Я думаю, это сводится к тому, имеют ли эти переменные какое-то фактическое значение в контексте класса (например, указатель на какую-то общую память, используемую всеми объектами) или просто некоторые временные данные, которые необходимо пройти между методами и а не загромождать класс. В последнем случае я бы определенно пошел с неназванным пространством имен. В первом, я бы сказал, это вопрос личного вкуса.
Я не согласен с другими ответами. Держите как можно больше из класса .
В редакции Scott Meyers' Effective C++ 3rd edition он рекомендует использовать функции класса non-friend . Таким образом, определение класса как можно меньше , доступ к личным данным осуществляется в нескольких местах, как возможно (инкапсулировано).
Следуя этому принципу, далее следует pimpl idiom. Однако необходим баланс . Убедитесь, что ваш код поддерживается. Blindly, , следуя этому правилу, заставит вас сделать все ваши личные методы локальным файлом и просто передать необходимые члены в качестве параметров.Это будет улучшить инкапсулирование, но уничтожить ремонтопригодность.
Все, что сказано, файлы локальных объектов очень трудно выполнить для тестирования. С некоторыми умными взломами вы можете получить доступ к частным членам во время модульных тестов. Доступ к локальным объектам файла немного больше involved.
Я согласен частично с Грегом в том, что неименованные элементы пространства имен не являются инкапсулированными, а не частными данными. В конце концов, инкапсуляция должна скрывать детали реализации от других модулей, а не от других программистов. Тем не менее, я действительно думаю, что есть некоторые случаи, когда это полезный метод.
Рассмотрим класс, как следующее:
class Foo {
public:
...
private:
static Bar helper;
};
В этом случае, любой модуль, который хочет использовать Foo также должны знать определение Bar, даже если это определение не имеет никакого значения то, что столь когда-либо. Подобные зависимости заголовков приводят к более частым и длительным перестроениям. Перемещение определения помощника в неназванное пространство имен в Foo.cpp - отличный способ разбить эту зависимость.
Я также категорически не согласен с тем, что неназванные пространства имен как-то менее читабельны или менее обслуживаемы, чем статические элементы данных. Удаление ненужной информации из вашего заголовка делает ее более кратким.
- 1. класса против пространств имен сферы
- 2. ссылки пространств имен в C# против VB.Net
- 3. C++ пространств имен trobles
- 4. C++ конфликтующих пространств имен
- 5. C++ пространств имен вопрос
- 6. понимание C пространств имен
- 7. C# ссылочной пространство имен спрятанных класса пространств имен
- 8. Отладка данных в «анонимных пространствах имен» (C++)
- 9. Использование для анонимных пространств имен в файлах заголовков
- 10. Использование пространств имен в C++
- 11. Назначение пространств имен в C++
- 12. скрытие пространств имен в C++
- 13. Использование пространств имен в C#
- 14. C++ пространств имен головных болей
- 15. анонимных класс двоичных имен
- 16. непостоянные статические члены в шаблоне/общего класса - C++ против C#
- 17. Использование пространств имен с C#
- 18. Почему несколько пространств имен?
- 19. .NET Несколько пространств имен для одного класса
- 20. Использование нескольких пространств имен для описания класса
- 21. Импортирование пространств имен в _ViewImports.cshtml
- 22. Импортирование вложенных пространств имен автоматически в C#
- 23. Использование встроенных пространств имен в C#
- 24. включают и использование пространств имен в C++
- 25. Xpath/C#, получая данные из нескольких пространств имен
- 26. Использование пространств имен в PHP
- 27. Использование пространств имен в библиотеках
- 28. пространство имен против класса вложенности
- 29. Несколько уровней пространств имен
- 30. C# 7.0 ValueTuples против анонимных типов
Имейте в виду, что это было в 90-х годах, и что компиляторы продвинулись до такой степени, что такие вещи, как «оптимизация всей программы VC++», работают достаточно хорошо, что такой рефакторинг является пустой тратой времени программиста. –
Уолтер Брайт сказал, что такой рефакторинг теперь пустая трата времени? Один из вопросов на этом заседании, касающийся проблем ремонтопригодности, был «кто, но вы сможете делать такие вещи, когда вы уходите на пенсию?» на что Вальтер ответил словами: «Когда я уйду на пенсию, компиляторы станут медленнее». –