Подтвердить что ты не робот

Должна ли вспомогательная функция входить в заголовок или в файл реализации?

При написании вспомогательного метода для класса в С++, следует ли его объявить как частный метод в определении класса в файле заголовка (.h)? Например:

/*Foo.h*/
class Foo {

     public:
         int bar();

     private:
         int helper();
};
...
/*Foo.cpp*/
...
int foo::bar() {
    int something = this->helper();
}

int foo::helper() {
    ...
}

Или, наоборот, лучше не объявлять его как частный член класса, а вместо этого просто делать его самостоятельной функцией в реализации?

/*Foo.h*/
class Foo {
    public:
        int bar();
};
...
/*Foo.cpp*/
...
int Foo::bar() {
    int something = helper();
    ...
}

int helper() {
    ...   
}
4b9b3361

Ответ 1

Свободная функция в файле реализации улучшает инкапсуляцию: ему не требуется декларация в заголовке, поэтому перекомпиляция клиентского кода при изменении его подписи по какой-либо причине не требуется. Для меня это достаточно хорошая причина, чтобы предпочесть этот вариант, когда это возможно. (Обязательно поместите его в анонимное пространство имен, чтобы предотвратить столкновения идентификаторов во время ссылки.)

Однако метод private имеет доступ к экземпляру класса и его частным частям с помощью указателя this. Если ему нужен такой доступ, то он должен быть либо методом, либо friend. В обоих случаях он будет отображаться в определении класса (заголовочный файл), а методы просто более удобны, чем друзья.

Ответ 2

Если ваша вспомогательная функция имеет смысл быть методом объекта, я почти всегда предпочел бы сделать ее функцией-членом, поэтому есть неявный указатель this, а не передать Foo * вспомогательной функции.

Если вспомогательная функция не должна быть методом объекта (то есть ей не нужен доступ к элементам данных или другим функциям-членам), тогда сделайте ее автономной функцией (static или в анонимное пространство имен, предпочтительно).

Ответ 3

Это немного субъективно, я думаю.

На мой взгляд, это зависит от того, имеет ли он какое-либо отношение к членам класса и/или ожидаете ли вы, что классы друзей будут использовать его (или производные классы в случае доступа protected).

Если функция фактически не работает ни с одним из членов, и никто ее не интересует, вы должны сохранить ее в файле реализации как статическую функцию. Кроме того, если это операция, которая должна быть быстрой, вы можете воспользоваться этой возможностью, чтобы сделать ее inline.

И наоборот, если функция работает над классом или может иметь дополнительные возможности использования в производных или связанных классах, сделайте ее членом.

Ответ 4

Моя позиция заключается в том, что заголовок содержит как можно меньше рекламы при достижении желаемых свойств дизайна и макета. Если есть опция, она переходит в исходный код. Некоторые внутренние детали требуют доступа к слишком многим внутренним деталям класса, чтобы сделать его жизнеспособным для реализации в процессе реализации.