Несколько классов в заголовочном файле по сравнению с единственным заголовочным файлом в классе

$(document).ready() - событие jQuery, которое происходит, когда документ HTML полностью загружен, а событие window.onload происходит позже, когда все, включая изображения на странице, загружено.

Также окно. onload - это чисто javascript-событие в DOM, а событие $(document).ready() - это метод в jQuery.

$(document).ready() обычно является оберткой для jQuery, чтобы убедиться, что все элементы, загруженные для использования в jQuery ...

Посмотрите на исходный код jQuery, чтобы понять, как он работает:

jQuery.ready.promise = function( obj ) {
    if ( !readyList ) {

        readyList = jQuery.Deferred();

        // Catch cases where $(document).ready() is called after the browser event has already occurred.
        // we once tried to use readyState "interactive" here, but it caused issues like the one
        // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
        if ( document.readyState === "complete" ) {
            // Handle it asynchronously to allow scripts the opportunity to delay ready
            setTimeout( jQuery.ready );

        // Standards-based browsers support DOMContentLoaded
        } else if ( document.addEventListener ) {
            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", completed, false );

            // A fallback to window.onload, that will always work
            window.addEventListener( "load", completed, false );

        // If IE event model is used
        } else {
            // Ensure firing before onload, maybe late but safe also for iframes
            document.attachEvent( "onreadystatechange", completed );

            // A fallback to window.onload, that will always work
            window.attachEvent( "onload", completed );

            // If IE and not a frame
            // continually check to see if the document is ready
            var top = false;

            try {
                top = window.frameElement == null && document.documentElement;
            } catch(e) {}

            if ( top && top.doScroll ) {
                (function doScrollCheck() {
                    if ( !jQuery.isReady ) {

                        try {
                            // Use the trick by Diego Perini
                            // http://javascript.nwbox.com/IEContentLoaded/
                            top.doScroll("left");
                        } catch(e) {
                            return setTimeout( doScrollCheck, 50 );
                        }

                        // detach all dom ready events
                        detach();

                        // and execute any waiting functions
                        jQuery.ready();
                    }
                })();
            }
        }
    }
    return readyList.promise( obj );
};
jQuery.fn.ready = function( fn ) {
    // Add the callback
    jQuery.ready.promise().done( fn );

    return this;
};

Также я создал изображение ниже как краткую ссылку для обоих:

68
задан Charles Menguy 26 April 2012 в 01:14
поделиться

10 ответов

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

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

Также Вы найдете, что о многих ошибках/диагностике сообщают через имя файла ("Ошибка в Myclass.cpp, строка 22"), и помогает, существует ли взаимно-однозначное соответствие между файлами и классами. (Или я предполагаю, что Вы могли назвать его от 2 до 1 корреспонденции).

73
ответ дан 24 November 2019 в 14:07
поделиться

Мы делаем это на работе, ее просто легче найти материал, если класс и файлы имеют то же имя. Что касается производительности, у Вас действительно не должно быть 5 000 классов в единственном проекте. Если Вы делаете, некоторый рефакторинг мог бы быть в порядке.

Однако существуют экземпляры, когда у нас есть несколько классов в одном файле. И это - когда это - просто частный класс помощника для основного класса файла.

11
ответ дан Magnus Westin 24 November 2019 в 14:07
поделиться

Разбитый тысячами строк кода?

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

, Но игравший с источниками после философии "позволяют нам соединить все", заключение состоит в том, что только тот, который записал файл, имеет любую надежду, которая не будет потеряна внутри. Даже с IDE, легко пропустить вещи, потому что , когда Вы играете с источником 20 000 строк, Вы просто закрываете свой ум для чего-либо не точно относящегося к Вашей проблеме.

Реальный пример: иерархия классов, определенная в тех, которые тысяча источников строк закрыла сама в ромбовидное наследование и некоторые методы, была переопределена в дочерних классах методами с точно тем же кодом. Это было легко пропущено (кто хочет исследовать/проверить 20 000 исходных кодов строк?), и когда исходный метод был изменен (исправление ошибки), эффект не был так же универсален, как исключено.

Зависимости, становящиеся круговыми?

у меня была эта проблема с шаблонным кодом, но я видел подобные проблемы с регулярным C++ и кодом C.

Разрушение Ваших источников в 1 заголовок на структуру/класс позволяет Вам:

  • Ускоряют компиляцию, потому что можно использовать предописание символа вместо включения целых объектов
  • , Имеют круговые зависимости между классами (В§) (т.е. класс A имеет указатель на B, и B имеет указатель на A)

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

Наличие отдельные заголовки делают код более модульным, быстрее для компиляции, и облегчают изучать его эволюцию через различные версии diffs

Для моей шаблонной программы, я должен был разделить свои заголовки на два файла:.HPP файл, содержащий объявление/определение шаблонного класса и.INL файл, содержащий определения упомянутых методов класса.

Помещение всего этого кода в одном и только одном уникальном заголовке означало бы помещать определения классов в начале этого файла и определения метода в конце.

И затем, если бы кому-то была нужна только небольшая часть кода с one-header-only решением, они все еще должны были бы заплатить за более медленную компиляцию.

(В§) Примечание, что у Вас могут быть круговые зависимости между классами, если Вы знаете, которым класс владеет который. Это - дискуссия о классах, имеющих знание существования других классов, не shared_ptr круговой антишаблон зависимостей.

Одно последнее слово: Заголовки должны быть автономными системами

Одна вещь, тем не менее, которую должно уважать решение нескольких заголовков и многочисленных источников.

, Когда Вы включаете один заголовок, неважно, какой заголовок, Ваш источник должен скомпилировать чисто.

Каждый заголовок должен быть автономной системой. Вы, как предполагается, разрабатываете код, не поиск сокровища путем хватания 10,000 + проект исходных файлов найти, какой заголовок определяет символ в этих 1 000 заголовков строк, которые необходимо включать только из-за один перечисление.

Это означает, что или каждый заголовок определяет или вперед - объявляют все символы, которые он использует, или включайте все необходимые заголовки (и только необходимые заголовки).

Вопрос о круговых зависимостях

подчеркнул , спрашивает:

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

underscore_d, 13 ноября в 23:20

Скажем, у Вас есть 2 шаблонов классов, A и B.

Скажем, определение класса A (resp. B) имеет указатель на B (resp. A). Давайте также скажем методы класса A (resp. B) на самом деле назовите методы от B (resp. A).

у Вас есть круговая зависимость и в определении классов и + реализациях их методов.

, Если бы A и B были нормальными классами и методами A и B, были в.CPP файлах, не было бы никакой проблемы: Вы использовали бы предописание, имели бы заголовок для каждого определения классов, тогда каждый CPP будет включать обоих HPP.

, Но поскольку у Вас есть шаблоны, на самом деле необходимо воспроизвести это шаблоны выше, но с заголовками только.

Это означает:

  1. заголовок определения A.def.hpp и B.def.hpp
  2. заголовок реализации A.inl.hpp и B.inl.hpp
  3. для удобства, "наивный" заголовок A.hpp и B.hpp

Каждый заголовок будет иметь следующие черты:

  1. В A.def.hpp (resp. B.def.hpp), у Вас есть предописание класса B (resp. A), который позволит Вам объявить указатель/ссылку на тот класс
  2. A.inl.hpp (resp. B.inl.hpp), будет включать и A.def.hpp и B.def.hpp, который включит методы из (resp. B) использовать класс B (resp. A).
  3. A.hpp (resp. B.hpp), непосредственно будет включать и A.def.hpp и A.inl.hpp (resp. B.def.hpp и B.inl.hpp)
  4. , Конечно, все заголовки должны быть сам достаточны, и защищены защитой заголовка

, начинающий пользователь будет включать A.hpp и/или B.hpp, таким образом игнорируя целую путаницу.

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

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

63
ответ дан Duncan Jones 24 November 2019 в 14:07
поделиться

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

8
ответ дан Matt Dillard 24 November 2019 в 14:07
поделиться

+1 для разделения. Я просто приехал на проект, где некоторые классы находятся в файлах с другим именем, или смешаны в с другим классом, и невозможно найти их быстрым и эффективным способом. Можно бросить больше ресурсов в сборку - Вы не можете составить потерянное время программиста, потому что он не может найти, что правильный файл редактирует.

7
ответ дан Chris Marasti-Georg 24 November 2019 в 14:07
поделиться

Большинство мест, где я работал, следовало этой практике. Я на самом деле записал стандарты кодирования для BAE (Австралия). наряду с причинами, почему вместо того, чтобы просто вырезать что-то в камне без реального выравнивания.

Относительно Вашего вопроса об исходных файлах, это не так много времени для компиляции, но больше проблема способности найти отрывок соответствующих норм во-первых. Не все используют IDE. И знание, что Вы просто ищете MyClass.h и MyClass.cpp действительно, экономит время по сравнению с рабочим "grep MyClass *. (h|cpp)" по набору файлов и затем отфильтровывания #include операторов MyClass.h...

Мышление Вы там - обходные решения для влияния больших количеств исходных файлов на времени компиляции. Посмотрите Крупномасштабную Разработку программного обеспечения C++ John Lakos для интересного обсуждения.

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

5
ответ дан Micha Wiedenmann 24 November 2019 в 14:07
поделиться

Это - обычная практика, чтобы сделать это, особенно быть в состоянии включать.h в файлы, которым нужен он. Конечно, производительность затронута, но попытка не думать об этой проблеме, пока это не возникает:).
лучше запуститься с разделенных файлов и после той попытки объединить .h's, которые являются наиболее часто используемыми вместе для улучшения производительности, если Вы действительно должны. Все это сводится к зависимостям между файлами, и это очень характерно для каждого проекта.

3
ответ дан kokos 24 November 2019 в 14:07
поделиться

Лучшая практика, как другие сказали, должна поместить каждый класс в свою собственную единицу перевода от обслуживания кода и перспективы понятности. Однако в крупномасштабных системах это иногда не желательно - видят, что раздел, наделенный правом ", Делает Те Исходные файлы Больше" в эта статья Bruce Dawson для обсуждения компромиссов.

3
ответ дан Brian Stewart 24 November 2019 в 14:07
поделиться

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

1
ответ дан 24 November 2019 в 14:07
поделиться

То же правило применяется здесь, но оно отмечает несколько исключений, где как оно позволяют так:

  • деревья Наследования
  • Классы, которые только используются в очень ограниченный объем
  • Некоторые Утилиты, просто помещаются в общий 'utils.h'
0
ответ дан Huppie 24 November 2019 в 14:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: