На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Разнести файл с классом на разные файлы (h + cpp)
    Всем хай!
    Сходу к проблеме.

    Есть такой код (условный простейший пример, проще не смогу придумать):
    ExpandedWrap disabled
      class A
      {
      public:
          A(const int pr)
          {}
      };
       
      class B: public A
      {
      public:
          B(const double pr) : A(pr)
          {}
      };
       
      void main(void)
      {
          return;
      }


    моя задача эту прожку разбить на 5 файлов: 2 файла с декларацией классов (.h), 2 файла реализации классов (.cpp) и тестирующий модуль (.cpp).

    ок, вот заголовочный файлы:
    ExpandedWrap disabled
      #ifndef CLASS_A
      #define CLASS_A
      class A
      {
      public:
          A(const int pr);
      };
      #endif


    ExpandedWrap disabled
      #include "A.h"
       
      #ifndef CLASS_B
      #define CLASS_B
      class B: public A
      {
      public:
          B(const double pr) : A(pr);
      };
      #endif


    вот файлы реализации:
    ExpandedWrap disabled
      #include "A.h"
      A::A(const int pr)
      {}


    ExpandedWrap disabled
      #include "B.h"
      #include "A.h"
       
          B::B(const double pr) : A(pr)
          {}


    и в итоге студия дает целых 14 ошибок!! жесть...
    особенно компилеру не нравится эта строка:
    ExpandedWrap disabled
      B::B(const double pr) : A(pr)


    какой тут нужен синтаксис???
      Препроцессор тут не так используется. Он должен оградить повторные включения заголовков, а не определений классов. Чтобы #include с определениями классов не зависели от порядка включения. В .cpp нужны только реализации методов и возможно определения статических полей данных.
      ExpandedWrap disabled
        // A.h
        class A
        {
        public:
            A(int pr);
        };
        // ---
         
        // B.h
        #include "A.h"
         
        class B: public A
        {
        public:
            B(double pr);
        };
        // ---
         
        // A.cpp
        #include "A.h"
         
        A::A(int pr) {}
        // ---
         
        // B.cpp
        #include "B.h"
         
        B::B(double pr) : A(pr) {}
        // ---
         
        // main.cpp
        #include "A.h"
        #include "B.h"
         
        A a(123);
        int main()
        {
            B b(321.0);
        }
        // ---
      Как-нибудь так...
        Цитата Qraizer @
        Препроцессор тут не так используется. Он должен оградить повторные включения заголовков, а не определений классов.

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

        все исправил, как в твоем примере, в итоге студия вот, что пишет:
        Ошибка 1 error C2011: 'A' : 'class' type redefinition
        Ошибка 3 error C2079: 'a' uses undefined class 'A'
        Ошибка 2 error C2504: 'A' : base class undefined

        уже гораздо лучше)) уже не 14 ошибок)

        P.S. вопрос вдогонку, если есть чисто виртуальная функция в базовом классе, то при разбивке на эти модули ведь слово "virtual" уже не пишется, так??

        Добавлено
        все заработал, как только исправил "A.h" так:

        ExpandedWrap disabled
          #ifndef CLASS_A
          #define CLASS_A
           
              class A
              {
              public:
                  A(int pr);
              };
           
          #endif


        зы: вопрос про виртуал открыт
          все понял, виртуал (чисто виртуальные функции) вообще не выносятся
            Цитата FasterHarder @
            все заработал, как только исправил "A.h" так:
            Ну да. За стражи написал, а написать забыл. Мой косяк.

            Добавлено
            Цитата FasterHarder @
            P.S. вопрос вдогонку, если есть чисто виртуальная функция в базовом классе, то при разбивке на эти модули ведь слово "virtual" уже не пишется, так??
            Цитата FasterHarder @
            все понял, виртуал (чисто виртуальные функции) вообще не выносятся
            Почему же. Выноси на здоровье. virtual является частью объявления, т.е. прототипа. Чтобы компилер проапдейтил структуру VMT. В определении virtual делать нечего, адрес метода в VMT линкер запишет.
              Цитата Qraizer @
              Почему же. Выноси на здоровье

              Если класс содержит чисто виртуальную функцию ----> он является абстрактным ----> как известно создавать конкретные экземпляры С++ не допускает ---> у абстрактный класс не нуждается в реализации как таковой ----> абстрактный класс описывается лишь в файле .h ----> виртуальные функции (чистые которые = 0) не выносятся

              неужели мои логические рассуждения имеют логическую ошибку...
                Ну как сказать... в целом да. чистые функции не нуждаются в реализации, но им не запрещается её иметь. Иногда иначе и нельзя, в случае чистого деструктора, например. (Непонятно, правда, зачем деструктору быть чистым... но это уже другой вопрос.)
                  Скрытый текст
                  Qraizer, а ты разве не знаешь в совершенстве стандарт ID3v2??)
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0505 ]   [ 17 queries used ]   [ Generated: 26.04.24, 17:18 GMT ]