WedX - журнал о программировании и компьютерных науках

Возможно ли иметь исходные файлы с одинаковыми именами в одном проекте Visual Studio C++?

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

MyClass
    \MyClass.cc (constructor)
    \functionForMyClass.cc
    \anotherFunctionForMyClass.cc 
OtherClass
    \OtherClass.cc (constructor)

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

Я работаю в Visual Studio 2008 и почему-то получил странные ошибки ссылок при использовании функции с одинаковым именем (и, следовательно, имени файла) в двух классах. По-видимому, это вызвано тем, что Visual Studio помещает все файлы .obj (по одному для каждого исходного файла) в один промежуточный каталог, перезаписывая ранее сгенерированные объектные файлы при компиляции исходных файлов с одинаковыми именами.

Это можно решить, поместив объектные файлы в подкаталоги на основе относительного пути к входному файлу. Visual Studio позволяет настраивать имена объектных файлов, которые она генерирует, и имеет макросы для использования там, но, похоже, нет макроса для «относительного пути к входному файлу».

Итак, есть ли способ заставить это работать? Если нет, то является ли использование одного проекта для каждого класса лучшим решением?

04.01.2010

  • Вы уверены, что VS перезаписывает ранее созданные объектные файлы? Какие ошибки ссылок вы получаете? 04.01.2010
  • @Serge: На самом деле кажется, что он пропускает компиляцию после компиляции первого исходного файла. Я добавил #error в файл, где определена отсутствующая функция, и ошибка компиляции не возникает. Переименование файла во что-то другое приводит к компиляции файла. В любом случае: после компиляции проекта остается только один объектный файл. 04.01.2010
  • Единственная хорошая вещь, которую я вижу здесь, это то, что вы пытаетесь узнать, как на самом деле работает VS2008, чтобы вы знали, где искать, когда кто-то еще загнал себя в угол - очень темный угол. 04.01.2010
  • @TC: причина, по которой я спросил, заключается в том, что я сделал тестовый проект с двумя исходными файлами с одинаковыми именами в разных каталогах в VS2005, и он отлично строится. VS добавляет «1» в конце имени второго объектного файла (например, test.obj и test1.obj). Так что, возможно, проблема не там, где вы думаете. 04.01.2010
  • @Serge: это проблема, появившаяся в VS2008. 04.01.2010
  • Является ли это хорошей практикой или нет, я не хотел бы обсуждать. Из интереса, что учитель говорит о перегруженных функциях? Я думаю, вы могли бы использовать искаженное компилятором имя функции в качестве имени файла в таких случаях, или пронумеровать их, или что-то в этом роде. Но мне любопытно узнать, что он рекомендует, и рассматривал ли он вообще перегрузку функций... 04.01.2010
  • @Steve Jossop: он предлагает пронумеровать их и поставить комментарий после объявления в заголовочном файле, документируя номер. 04.01.2010
  • @ТС. Ой. Как насчет перегрузки оператора? Бесплатные функции в анонимном пространстве имен? 04.01.2010
  • Перегрузка оператора: operatorassign.cc, не знаю о бесплатных функциях. 04.01.2010
  • Здесь также дан ответ: [Visual Studio 2010 и 2008 не могут обрабатывать исходные файлы с одинаковыми именами в разных папках?] [1] [1]: stackoverflow.com/questions/ 3729515/ 16.04.2015

Ответы:


1

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

https://img37.imageshack.us/img37/3695/outputfile.png

PS. Похоже, у лектора стоит дрянной (вероятно, написанный самим лектором) автоматический верификатор кода, который накладывает это ограничение. Чтобы получить дополнительные оценки, предложите переписать парсер, чтобы он работал с нормальной/разумной/не странной компоновкой проекта.

04.01.2010
  • В частности, Игорь говорит, что вам нужно щелкнуть правой кнопкой мыши каждый потенциально конфликтующий файл и изменить его свойства. 05.01.2010
  • Взгляните на stackoverflow.com/a/3731577/17349 - кажется, вы можете указать настройку для всего проекта, которая работает Эта проблема 02.08.2012

  • 2

    Реальный ответ:

    Изменять

    C/C++ => Выходные файлы => Имя выходного файла

    to

    $(IntDir)/%(RelativeDir)/

    Каждый файл .obj будет создаваться в подпапке, чтобы он не перезаписывал предыдущий при связывании.

    12.01.2015
  • Проголосовал за, это было то, что я искал в Google. Я делал это какое-то время, но забыл, что именно я сделал... 02.08.2015

  • 3

    Я не могу придумать, как изменить настройки проекта, чтобы заставить VStudio автоматически разбивать промежуточные файлы на отдельные папки.

    У вас есть несколько шансов -

    1. Встройте имя класса в каждое имя файла. Большинство IDE отображают только имя файла в виде вкладки, поэтому, если у вас есть несколько методов в разных классах с одним и тем же именем, их будет сложно отличить друг от друга, если имя файла не включает имя класса вместе с именем метода. . Именно поэтому я считаю, что советы твоих учителей - безумие. Я не видел ни одного руководства по стилю программирования, поддерживающего такой подход. Кроме того, это прямо противоречит тому, как работают различные инструменты: если вы используете Visual Studio для создания класса, он создает один файл cpp и один заголовок и автоматически добавляет каждую новую функцию в один файл cpp.

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

    3. Переключите курсы информатики на те, которые не преподаются сумасшедшим. Серьезно, этот парень полностью оторван от лучших отраслевых практик и пытается навязать своим ученикам свои странные идеи: идеи, которые придется забыть, как только они покинут преподавательскую среду.

    04.01.2010
  • +1, особенно за пункт 3. Убирайтесь к черту с этого курса, он принесет вам больше вреда, чем пользы. 04.01.2010
  • Если только это не является предпосылкой для хороших вещей позже. Страдание от определенного количества сумасшествия ради достойной долгосрочной цели не является полностью бесполезным опытом ;-) 04.01.2010
  • Я (ТС) здесь со Стивом. Я был самоучкой в ​​C++, и курс и его преподаватель определенно значительно улучшили мои способности. И есть метод безумия: такая организация имеет как преимущества (время компиляции, небольшие аккуратные исходные файлы), так и недостатки. Я просто делаю то, что я делаю в любом курсе: будьте критичны, не принимайте слепо все, что предлагается, и выбирайте те части, которые я считаю полезными :) 04.01.2010
  • Иногда даже самые неортодоксальные методы преподают нам ценный урок - как нельзя что-то делать. 05.01.2010

  • 4

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

    04.01.2010

    5

    Можете ли вы использовать имя класса в имени файла для устранения неоднозначности? Я думаю, что у вас может быть

    MyClass \MyClass.cc (конструктор) \function1_MyClass.cc \function2_MyClass.cc

    Это означало бы, что у каждого файла будет достаточно уникальное имя, чтобы решить проблему. Это приемлемая стратегия?

    04.01.2010

    6

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

    Посмотрев файлы справки, я думаю, вам следует перейти в свойства проекта/C C++/Outpuf Files/Object File Name: и ввести $(InputDir) (без обратной косой черты). Затем каждый исходный файл должен наследовать это свойство, а ваши .obj файлы должны быть разделены.

    Возможно, вам придется выполнить Clean Solution, прежде чем вносить какие-либо изменения.

    04.01.2010

    7
    • Переименование объектных файлов будет работать, но это будет мучительно, и замедлит цикл компиляции/компоновки. Я никогда не понимал, почему, но кажется, что Visual Studio сбивает с толку, если объектные файлы не имеют имен по умолчанию.

    • Вы можете добавить префикс имени функции к имени класса; например myclass-ctor.cc, myclass-function1.cc и т. д.

    • У вас может быть один файл .cc для каждого класса, который # включает отдельные файлы функций. В этом случае вам необходимо запретить компиляцию файлов #include отдельно (либо переименуйте их расширение, либо установите «Свойства» -> «Исключить из сборки» на «Да»).

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

    Если нет, то является ли использование одного проекта для каждого класса лучшим решением?

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

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

    04.01.2010

    8

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

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

    04.01.2010
  • Покажите мне, как вы можете поместить две функции-члена объявления в отдельные файлы заголовков.... (-1) 04.01.2010
  • В вопросе требуется объявление класса (и члена) в одном заголовочном файле, а каждая функция-член определение в отдельном исходном файле. Этого можно добиться, имея отдельный файл для каждого определения функции, который #включается в один исходный файл. Файлы #include не должны компилироваться отдельно. 04.01.2010

  • 9

    В Visual Studio 2010 я установил

        Properties -> C/C++ -> Output Files -> Output File Name
    

    to

        V:\%(Directory)$(PlatformName)_$(ConfigurationName)_%(Filename).obj
    

    чтобы файлы OBJ оказались рядом с исходниками, предполагая, что проект находится на диске V (пока не знаю, есть ли для него макрос).

    Кстати: $(InputDir) относится к каталогу решения/проекта и вызовет ту же проблему в другом каталоге.

    30.08.2012
    Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

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

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]