Есть ли какой-то недостаток, если использовать только файлы cpp без отдельных заголовочных файлов? - PullRequest
2 голосов
/ 19 декабря 2009

Я нашел несколько потоков, объясняющих, почему C ++ разделяет файлы .cpp и .h (например, здесь ). Мне было бы интересно узнать, вызывает ли это какую-либо проблему, если я не разделяю их. Я не хочу делиться объектными файлами, так в чем же преимущество разделения в небольшом проекте? Если это просто замедляет время компиляции, это не имеет большого значения, по моему мнению. Я хочу повторно реализовать Java-программу на C ++, поэтому мне кажется, что намного проще хранить класс только в одном файле. Пример:

// Hello.cpp
#ifndef HELLO_20091218
#define HELLO_20091218

#include <iostream>
#include "Utils.cpp"

class Hello
{
public:
    void start()
    {
        std::cout << Utils::nrand(100) << "\n";
        // Utils and all other classes are written in a similar way
    }
};

#endif

Есть вещь, которая беспокоит меня. «Определение функции-члена внутри класса требует от реализации расширять вызовы внутри нее». Так что, если я так делаю, все помечается как встроенное. Приведет ли это к большему исполняемому файлу или другим недостаткам?

Ответы [ 4 ]

3 голосов
/ 19 декабря 2009

В C и C ++ наименьшей единицей компиляции является файл. Если вы просто не используете заголовочные файлы и включаете все в свой «основной» файл, каждый раз, когда вы что-то меняете, вся ваша программа должна перекомпилироваться. Для больших приложений это может быть очень хорошим аргументом для разделения заголовка и реализации. Также, если другая часть вашего приложения будет жить в другом двоичном исполняемом файле, и вы не захотите повторно использовать классы, вы в безопасности с заголовочными файлами, в то время как вы получите много дополнительных ресурсов без них.

Если вас это не волнует (вы об этом пожалеете), вам не нужны отдельные заголовочные файлы.

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

3 голосов
/ 19 декабря 2009

Это действительно два вопроса.

Прямо сейчас, то, что вы показали выше как «Hello.cpp», выглядит как заголовок с завершающей защитой. Компилятору на самом деле все равно, какое имя вы дадите заголовку, но включение файла .cpp может сбить с толку (в лучшем случае) любого, кто смотрит на ваш код. Если вы компилируете это самостоятельно, функция include guard (по крайней мере), вероятно, должна пойти - хотя это не вызывает реальной проблемы, в лучшем случае это бессмысленно и запутанно.

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

2 голосов
/ 19 декабря 2009

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

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

То, что такие слова, как package , library и API , так сильно нагружены альтернативными техническими значениями, свидетельствует о важности, которую разработчики имеют для такого устройства.

Если вы думаете, что в будущем у класса, который вы написали, есть возможность повторного использования, было бы неплохо разбивать отдельные файлы .cpp и .h, чтобы вы могли легко ссылаться на них в другом проекте. Что касается штрафов за скорость компиляции, рассмотрим долгосрочные выгоды в сравнении с затратами. (И что компиляторы и аппаратные средства имеют тенденцию становиться быстрее с каждым годом.)

1 голос
/ 19 декабря 2009

«Когда в Риме делают так, как делают римляне»

Вы обмануты, думая, что у вас есть выбор использовать C ++ так же, как Java. Хотя это технически правильно, вы нарушаете некоторые очень строгие соглашения, которые существуют по определенной причине. Вы также можете легко начать использовать new, не вызывая delete, потому что «это не имеет большого значения» или «ваша программа маленькая» или «ОС освободит всю память после закрытия вашей программы», но это не значит, что должен сделать это. Я согласен с тем, что C ++ более сложен, чем Java, и что это может быть настоящей болью, но с этим вам придется иметь дело. Это то, что каждый разработчик C ++ рано или поздно принимает.

...