Считается ли плохой формой в C ++ помещать объявление класса, содержащее определения методов, в заголовочный файл? - PullRequest
2 голосов
/ 17 декабря 2010

Я привык к C, где заголовочные файлы обычно содержат только объявления, а не определения, но C ++, кажется, поощряет смешивание обоих, по крайней мере, с классами.Возьмите это объявление класса, которое может быть легко помещено в заголовочный файл.Некоторые из его методов определены inline, не в смысле ключевого слова inline, а inline, как в самом объявлении класса.В частности, конструктор и четыре метода получения / установки.

MyClass.h:

    class MyClass {
        public:
            MyClass(int a = 0, int b = 1) : _a(a), _b(b)  {};
            int getA() { return _a; };
            int getB() { return _b; };
            void setA(int a) { _a = a; };
            void setB(int b) { _b = b; };
            void doSomething(); // no definition here; defined in source file
            void doSomething2(); // no definition here; defined in source file
            void doSomething3(); // no definition here; defined in source file
        private:
            int _a;
            int _b;
    };

Это плохая форма, и я должен определять методы класса отдельно в исходном файле, оставляя только объявления методов в объявлении класса, или это совершенно приемлемо?

Ответы [ 3 ]

7 голосов
/ 17 декабря 2010

Это может быть дурной тон, в зависимости от "большей картины" приложений, использующих заголовок.Помещая реализацию в заголовок, вы требуете модификации заголовка, когда эта реализация изменяется ... такие изменения вызывают / требуют перекомпиляции объекта клиента во многих системах сборки (например, make).В отличие от этого, внеплановые изменения могут потребовать повторного связывания, и при использовании совместно используемых библиотек эти библиотеки можно будет заменить без каких-либо изменений в клиентских приложениях.Следовательно, когда нет особой причины использовать встраивание, низкоуровневые заголовки, используемые многими приложениями, как правило, предпочитают внеплановую реализацию.Это особенно актуально, когда ожидается, что реализация потребует изменений.

Другая причина, по которой некоторые люди предпочитают разделять реализацию, состоит в том, чтобы не вводить в заблуждение людей, читающих API как форму документации.Когда читать меньше, это, как правило, понятнее, хотя иногда реализация помогает понять функциональность.Но программисты, которые видят реализацию, склонны думать о поведенческих последствиях и последствиях для производительности и создавать клиентский код, который зависит от этого, даже если интерфейс не дает таких строгих гарантий: это делает клиентский код хрупким в случае изменения реализации.*

5 голосов
/ 17 декабря 2010

Мало того, что это приемлемо, оно выполняет что-то немного отличное от помещения определений методов в файл .cpp. Метод, определенный внутри блока class, неявно inline.

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

Делать не помещать определения методов за пределы блока class, но внутри файла заголовка, если только вы явно не пометите их inline.

Придирка: вы не должны начинать идентификаторы с подчеркивания. У вас нет зарезервированных идентификаторов, но стоит избегать начальных подчеркиваний.

3 голосов
/ 17 декабря 2010

Нет, это вполне приемлемо, а в случае встроенных функций или шаблонов иногда почти необходимо.

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

...