"Традиционный" класс C++ (просто некоторые случайные объявления) мог бы напомнить следующее:
class Foo
{
public:
Foo();
explicit Foo(const std::string&);
~Foo();
enum FooState
{
Idle, Busy, Unknown
};
FooState GetState() const;
bool GetBar() const;
void SetBaz(int);
private:
struct FooPartialImpl;
void HelperFunction1();
void HelperFunction2();
void HelperFunction3();
FooPartialImpl* m_impl; // smart ptr
FooState m_state;
bool m_bar;
int m_baz;
};
Я всегда находил этот тип спецификации уровня доступа ужасным и трудным следовать, если исходный программист не организовывал свои "регионы доступа" аккуратно.
Смотря на тот же отрывок в стиле Java/C#, мы добираемся:
class Foo
{
public: Foo();
public: explicit Foo(const std::string&);
public: ~Foo();
public: enum FooState
{
Idle, Busy, Unknown
};
public: FooState GetState() const;
public: bool GetBar() const;
public: void SetBaz(int);
private: struct FooPartialImpl;
private: void HelperFunction1();
private: void HelperFunction2();
private: void HelperFunction3();
private: FooPartialImpl* m_impl; // smart ptr
private: FooState m_state;
private: bool m_bar;
private: int m_baz;
};
По-моему, это намного легче считать в заголовке, потому что спецификатор доступа прямо рядом с целью и не набором строк далеко. Я нашел это особенно верным при работе с кодом шаблона только для заголовка, который не был разделен на обычное "*.hpp / *.inl" пара. В том сценарии размер реализаций функции пересилил эту маленькую, но важную информацию.
Мой вопрос прост и происходит от того, что я никогда не видел, что кто-либо еще активно делает это в их коде C++.
Предположение, что у меня нет "Представления класса" способным IDE, является там какими-либо очевидными недостатками к использованию этого уровня многословия?
Любые другие рекомендации стиля приветствуются!
«Находясь в Риме, делайте, как римляне».
. Мне, проведя много времени с Java, нравится стиль указания спецификаторов доступа для каждого поля и метода отдельно. Однако, когда я программирую на C ++, я всегда использую стиль, показанный в вашем первом фрагменте кода.
В этом нет ничего плохого, хотя вы удивитесь. Основное преимущество разделения спецификаторов доступа заключается в том, что это способствует размещению всех закрытых членов и методов в верхней части класса - вместе.
Если ваш класс слишком велик, чтобы поместиться на одном экране, его, вероятно, следует либо разбить на более чем один класс, и / или любые неявно встроенные функции должны быть явно объявлены встроенными с реализацией, перемещенной из класса.
Лично меня очень раздражает необходимость указывать квалификатор доступа для каждого символа. Это усложняет чтение, а не упрощает, и поощряет очень плохую привычку свободно смешивать частные и общедоступные вещи во всем определении класса. Я все время вижу такой беспорядок. В C # я пытаюсь смягчить это с помощью #region private
и т. Д., Что, надеюсь, побуждает будущих сопровождающих сохранять все в чистоте.
Действительно, семантически это не имеет значения, но вы окажете себе и своим коллегам большую услугу, если будете просто следовать принятому.
Лично мне нравится мой класс так:
struct S {
S(int m) : m(m) { }
S(const S& o);
S& operator=(const S& o);
void f() const;
std::string g();
private:
void help();
private:
int m;
};
Но я изменю свои манеры, не раздумывая дважды, если сделаю фиксацию в репозиторий, который не является строго моим, потому что я знаю, как я был бы благодарен, если бы кто-то передал свои код в мои репозитории в соответствии с моими обычаями.
Недостаток последнего подхода в том, что он редко выполняется, и не стоит удивлять таким образом других разработчиков, и требует миллион раз набирать модификатор доступа. Использование традиционного подхода избавит от необходимости набирать модификатор снова и снова, а также является ожидаемым подходом.