Почему main.cpp требуется с QtCreator [duplicate]

Мой первый подход к этой проблеме был похож на тот, который был отправлен @Jeeped:

  1. загружать входные столбцы в массив и подсчитывать строки в каждом столбце
  2. заполнить массив все комбинации
  3. присваивают массив выходному диапазону

Используя MicroTimer Я вычислил среднее время, затраченное каждой частью алгоритма. Часть 3. заняла 90% -93% от общего времени выполнения для больших входных данных.

Ниже я попытался улучшить скорость записи данных на рабочий лист. Я определил константу iMinRSize=17. После того, как возможно заполнить более iMinRSize последовательные строки с тем же значением, код прекратит подавать массив и будет записываться непосредственно в диапазон рабочих листов.

Sub CrossJoin(rSrc As Range, rTrg As Range)

  Dim vSrc() As Variant, vTrgPart() As Variant
  Dim iLengths() As Long
  Dim iCCnt As Integer, iRTrgCnt As Long, iRSrcCnt As Long
  Dim i As Integer, j As Long, k As Long, l As Long
  Dim iStep As Long

  Const iMinRSize As Long = 17
  Dim iArrLastC As Integer

  On Error GoTo CleanUp
  Application.ScreenUpdating = False
  Application.EnableEvents = False

  vSrc = rSrc.Value2
  iCCnt = UBound(vSrc, 2)
  iRSrcCnt = UBound(vSrc, 1)
  iRTrgCnt = 1
  iArrLastC = 1
  ReDim iLengths(1 To iCCnt)
  For i = 1 To iCCnt
    j = iRSrcCnt
    While (j > 0) And IsEmpty(vSrc(j, i))
      j = j - 1
    Wend
    iLengths(i) = j
    iRTrgCnt = iRTrgCnt * iLengths(i)
    If (iRTrgCnt < iMinRSize) And (iArrLastC < iCCnt) Then iArrLastC = iArrLastC + 1
  Next i

  If (iRTrgCnt > 0) And (rTrg.row + iRTrgCnt - 1 <= rTrg.Parent.Rows.Count) Then
    ReDim vTrgPart(1 To iRTrgCnt, 1 To iArrLastC)

    iStep = 1
    For i = 1 To iArrLastC
      k = 0
      For j = 1 To iRTrgCnt Step iStep
        k = k + 1
        If k > iLengths(i) Then k = 1
        For l = j To j + iStep - 1
          vTrgPart(l, i) = vSrc(k, i)
        Next l
      Next j
      iStep = iStep * iLengths(i)
    Next i

    rTrg.Resize(iRTrgCnt, iArrLastC) = vTrgPart

    For i = iArrLastC + 1 To iCCnt
      k = 0
      For j = 1 To iRTrgCnt Step iStep
        k = k + 1
        If k > iLengths(i) Then k = 1
        rTrg.Resize(iStep).Offset(j - 1, i - 1).Value2 = vSrc(k, i)
      Next j
      iStep = iStep * iLengths(i)
    Next i
  End If

CleanUp:
  Application.ScreenUpdating = True
  Application.EnableEvents = False
End Sub

Sub test()
  CrossJoin Range("a2:f10"), Range("k2")
End Sub

Если мы установим iMinRSize в Rows.Count , все данные записываются в массив. Ниже приведены мои тестовые результаты:

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

3
задан LCsa 2 September 2014 в 20:23
поделиться

2 ответа

(Примечание. Полный ответ должен содержать комментарий @ thokra, который означает, что main.cpp является именем файла, а внешний вид точки входа в программу в файле с этим именем является только условным. довольно хорошо придерживался соглашения в Qt-программах и C ++ вообще, чтобы попытаться поместить точку входа в файл с таким именем.)

Одной категорией будет регистрация глобальных перехватов и настроек , Подумайте о таких вещах, как qInstallMessageHandler или QTextCodec :: setCodecForCStrings .

Инициализация любых библиотек non-Qt , которые ваше приложение хочет воспринимать как нечто само собой разумеющееся, будет другой областью.

Если ваша программа имеет объект главного окна, который только создается и уничтожается один раз, может показаться одинаково подходящим поставить код «запустить один раз» в его конструктор / деструктор. Но спросите себя, что это такое о вашем приложении, которое позволяет ему иметь только одно главное окно. Почему бы ему не иметь два в одном процессе? Даже если это не является частью сегодняшнего требования, оно может предложить архитектурную границу.

В личном опыте я упомянул, что если вы попытаетесь сделать класс, полученный из QApplication, а затем поместите свой глобальный запуск -код в конструкторе и деструкторе этого производного класса, что сложнее, чем кажется (особенно если вы создаете потоки и делаете виджеты в этом конструкторе) . Поэтому я не думаю, что в большинстве сценариев вы должны получить от QApplication. Я застрял в этом, потому что я создавал приложение framework ... но избегайте этого, и ваш код запуска выполняется в main.cpp.

6
ответ дан HostileFork 24 August 2018 в 22:27
поделиться

"1. Является ли единственная цель main.cpp запуска приложения?"

Как из [определение стандартов] 1 в первом разделе говорится:

3.6 Начало и окончание [basic.start] 3.6.1 Основная функция [basic.start.main] 1 Программа должна содержать глобальную функцию main, которая является назначенным началом программы. Реализация определяется, требуется ли программа в автономной среде для определения основной функции. [Примечание: В автономной среде запуск и завершение определяются реализацией; startup содержит выполнение конструкторов для объектов области пространства имен со статической продолжительностью хранения; завершение содержит выполнение деструкторов для объектов со статической продолжительностью хранения. -end note]

Приложение все еще использует C ++, таким образом это ограничение должен быть удовлетворен для любого исполняемого приложения. Предположительно: Да, единственная цель main() - запустить приложение.

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

3
ответ дан πάντα ῥεῖ 24 August 2018 в 22:27
поделиться