Как включить по умолчанию все заголовки в каталоге

Я прохожу упражнения книги C++. Для каждого осуществления я хочу минимизировать шаблонный код, который я должен написать. Я настроил свой проект определенный путь, но он не кажется правильным и требует слишком многих изменений.

Прямо сейчас у меня есть сингл main.cpp файл со следующим:

#include "e0614.h"
int main()
{
    E0614 ex;
    ex.solve();
}

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

Таким образом, мои вопросы:

  1. Я могу включать все заголовки в каталог так, по крайней мере, я не должен изменяться #include строка?
  2. Еще лучше могу я переписывать свое решение так, чтобы я даже не затрагивал main.cpp, не имея одного файла со всем кодом для каждого упражнения в нем?

Обновление:

Я закончил тем, что следовал совету _ Poita для генерации main.cpp с помощью сценария.

Так как я использую IDE (Visual Studio), я хотел, это интегрировалось с нею, поэтому провел немного исследования на как. Для заинтересованных, в как, продолжает читать (это было справедливо, но не полностью, просто).

Visual Studio позволяет Вам использовать внешний инструмент с помощью меню Tools-> External Tools и содержит набор предварительно определенных переменных, такой как $(ItemFileName), который может быть передан инструменту. Таким образом в этом экземпляре я использовал простой пакетный файл, и он передается название в настоящее время выбираемого файла в Visual Studio.

Чтобы добавить что инструмент к панели инструментов, щелкните правой кнопкой по панели инструментов, выбор Настраивают-> Команды-> Инструменты, и выбирают "Внешнюю Команду X" и перетаскивают его на панель инструментов. Займите место X с числом, соответствующим инструменту, который Вы создали. Моя установка содержала 5 предсуществовавших инструментов значения по умолчанию, перечисленных в Инструментах-> Внешние Инструменты, таким образом, тот, который я создал, был инструментом номер 6. Необходимо выяснить это число, поскольку его не показывают. Можно затем присвоить значок ярлыку (это - команда BuildMain, показанная ниже):

alt text

10
задан Glorfindel 29 June 2019 в 16:05
поделиться

10 ответов

  1. Нет. Вы должны включить их все, если хотите.

  2. Нет. По крайней мере, не так, чтобы сэкономить на печатании.

Конечно, вы могли бы написать сценарий для создания main.cpp для вас ...

15
ответ дан 3 December 2019 в 16:09
поделиться

Если вы работаете в системе Unix, у вас может быть программная ссылка, указывающая на последнее упражнение.

ln -s e0615.h latest.h

и назовите свой класс E вместо E0614, конечно

P.S. Насколько мне известно, вы не можете сделать #include xxx *

3
ответ дан 3 December 2019 в 16:09
поделиться

Не используйте один файл main.cpp, который вы изменяете для каждого упражнения. Это решение использует встроенные правила make, поэтому вам нужно только ввести make e0614 , и он сгенерирует e0614.cpp, скомпилирует и свяжет его. Вы можете настроить каждый файл .cpp (они не будут регенерироваться, как написано ниже) и поддерживать всю эту историю, чтобы обращаться к ней по мере выполнения упражнений, а не стирать ее при переходе от одного к другому. . (Вы также должны использовать систему управления версиями, например Mercurial .)

Makefile

e%.cpp:
        ./gen_ex_cpp $@ > $@

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

Пример сценария создания

#!/usr/bin/python
import sys
args = sys.argv[1:]
if not args:
  sys.exit("expected filename")
name = args.pop(0).partition(".")[0]
if args:
  sys.exit("unexpected args")
upper_name = name.upper()
print """
#include "%(name)s.hpp"
int main() {
  %(upper_name)s ex;
  ex.solve();
  return 0;
}
""" % locals()
1
ответ дан 3 December 2019 в 16:09
поделиться

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

Это действительно плохая идея - включать *, даже если бы вы могли.

0
ответ дан 3 December 2019 в 16:09
поделиться
sed -i 's/\<\\([eE]\\)[0-9]+\\>/\19999/' main.cpp

Замените 9999 нужным числом. Могут быть способы получше.

0
ответ дан 3 December 2019 в 16:09
поделиться

Если вы собираете код с помощью make, у вас должно получиться следующее.

Могу ли я включить все заголовки в каталог, чтобы хотя бы не менять строку #include?

Измените вашу строку include на что-то вроде #include . Теперь вы можете позволить вашему Makefile автоматически генерировать all_headers.h с целью типа:

all_headers.h:
    for i in `ls *.h`; do echo "#include <$i>" >>all_headers.h; done

Убедитесь, что all_headers.h удаляется при 'make clean'.

Еще лучше, могу ли я переписать свое решение так, чтобы мне даже не пришлось трогать main.cpp, не имея одного файла со всем кодом для каждого упражнения в нем?

Вы можете сделать это, если абстрагируете свой класс с помощью typedef. В вашем примере измените имя класса с E0614 на myClass (или что-то в этом роде). Теперь добавьте в Makefile под циклом for строку echo "typedef "$MY_TYPE" myClass;" >>all_headers.h. Когда вы собираете свою программу, вызовите 'make' с помощью чего-то вроде make MY_TYPE=E0614, и ваш typedef будет автоматически заполнен классом, который вы хотите протестировать.

9
ответ дан 3 December 2019 в 16:09
поделиться

Вы можете использовать условную компиляцию для имени класса с помощью конкатенации.

// Somewhere in your other files
define CLASS_NUMBER E0614

// in main.cpp
#define ENTERCLASSNUMBER(num) \
##num## ex;

// in main()
ENTERCLASSNUMBER(CLASS_NUMBER)

Однако не знаю, как насчет include. Как было предложено выше, лучшим вариантом может быть скрипт.

0
ответ дан 3 December 2019 в 16:09
поделиться

Почему бы не использовать объектные механизмы?

Вы можете использовать для этого стратегию Exemplar.

class BaseExercise
{
public:
  static bool Add(BaseExercise* b) { Collection().push_back(b); return true; }
  static size_t Solve() {
    size_t nbErrors = 0;
    for(collections_type::const_iterator it = Collection().begin(), end = Collection().end(); it != end; ++it)
      nbErrors += it->solve();
    return nbErrors;
  }

  size_t solve() const
  {
    try {
      this->solveImpl();
      return 0;
    } catch(std::exception& e) {
      std::cout << mName << " - end - " << e.what() << std::endl;
      return 1;
    }
  }
protected:
  explicit BaseExercise(const char* name): mName(name)
  {
  }
private:
  typedef std::vector<BaseExercise*> collection_type;
  static collection_type& Collection() { collection_type MCollection; return MCollection; }

  virtual void solveImpl() const = 0;

  const char* mName;
}; // class BaseExercise

template <class T>
class BaseExerciseT: public BaseExercise
{
protected:
  explicit BaseExerciseT(const char* b): BaseExercise(b) { 
    static bool MRegistered = BaseExercise::Add(this);
  }
};

Хорошо, это база.

// Exercise007.h
#include "baseExercise.h"

class Exercise007: public BaseExerciseT<Exercise007>
{
public:
  Exercise007(): BaseExerciseT<Exercise007>("Exercise007") {}
private:
  virtual void solveImpl() const { ... }
};

// Exercise007.cpp
Exercise007 gExemplar007;

И для main

// main.cpp
#include "baseExercise.h"

int main(int argc, char* argv[])
{
  size_t nbErrors = BaseExercise::Solve();
  if (nbErrors) std::cout << nbErrors << " errors" << std::endl;
  return nbErrors;
}

И здесь вам не нужен скрипт;)

0
ответ дан 3 December 2019 в 16:09
поделиться

попробуйте следующее: -

#ifndef a_h
#define a_h

#include <iostream>
#include <conio.h>
#incl....as many u like
class a{
f1();//leave it blank
int d;
}
#endif //save this as a.h

позже включите это в основную программу ur, которая является файлом cpp

#include "a.h"

... вашей программой

-2
ответ дан 3 December 2019 в 16:09
поделиться

Написание правила make-файла для передачи имени исполняемого файла в качестве параметра -DHEADERFILE = something в компилятор не должно вызывать затруднений. Что-то вроде:

%.exe : %.h %.cpp main.cpp
    gcc -o $< -DHEADER_FILE=$<F $>

OTOH, я не знаю, выполняет ли #include расширение макроса в имени файла.

0
ответ дан 3 December 2019 в 16:09
поделиться
Другие вопросы по тегам:

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