На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Ошибка С2504 - не определен базовый класс
    Доброе время суток
    ПОМОГИТЕЕЕЕЕЕ!!!!Пожалуйста :rolleyes:

    Суть вот в чем:

    ExpandedWrap disabled
      base.h base
      pragma once
      class Cbase
      {
      //...
      };
       
      base.cpp base
      //реализация base


    ExpandedWrap disabled
      child.h child
      pragma once
      class Cchild: public Cbase
      {
      //...
      };
       
      child.cpp
      #include "base.h"
      #include "child.h"
      //Реализация Cchild


    Все работало!!!!!!
    Добавляю так же Cchild2 - И ОШИБКА!!!! :unsure: :wacko:
    Удалил из проекта файлы Cchild2!!! Все равно эта ошибка :unsure: :wall:
    Вот че это за ... такая? :unsure:
    Сообщение отредактировано: agapUP -
      Опубликуй весь код нормально, ибо приходится только гадать.
      А если "убираешь" модули (классы) - пересобирай проект полностью, с удалением старых объектных модулей.
        Цитата agapUP @
        Вот че это за ... такая? :unsure:

        А с чего ты вдруг решил что оно по другому должно работать? Вот ты написал:
        ExpandedWrap disabled
          child.h child
          pragma once
          class Cchild: public Cbase
          {
          //...
          };

        Расскажи пожалуйста, откуда компилятор, при компиляции этого кода будет знать что такое CBase и где он объявлен?
        Ты не пробовал #include "base.h" подключить в *.h файл?

        Добавлено
        Цитата agapUP @
        Все работало!!!!!!

        Очень странно что оно все работало. Не должно было работать, должно было выдать вот такую ошибку, которую ты сейчас и получил.
        Сообщение отредактировано: KILLER -
          Цитата KILLER @
          Ты не пробовал #include "base.h" подключить в *.h файл?

          Подключил - работает! НО! Разве я этого не писал?...
          ExpandedWrap disabled
            ...
            child.cpp
            #include "base.h"
            #include "child.h"


          Тут какая логика, этот "Cbase" - общие алгоритмы: нутация, расчет векторов и т.д...
          Его поля и методы используются, скажем, в Child1,Child2,Child3....
          Теперь обобщенная логика main():
          ExpandedWrap disabled
            #include "child1.h"
            #include "child2.h"
            #include "child3.h"
            //...
             
            void main()
            {
            //Задача 2
            child2.task()
            //Анализ данных
            //...
            //Задача 1
            child1.task()
            //Анализ данных
            //...
            //Задача 1
            child3.task()
            //Анализ данных
            //...
            }

          И тут возникает вопрос: а что мне скажет компилятор на многократное подключение "base.h"? :unsure:
            Цитата agapUP @
            И тут возникает вопрос: а что мне скажет компилятор на многократное подключение "base.h"?

            Ничего не скажет, pragma once для этого и нужен, чтобы включал только один раз
            Сообщение отредактировано: Kray74 -
              Цитата agapUP @
              Разве я этого не писал?...

              Это ты написал в cpp файле, после отработки препроцессора, у тебя в твой cpp файл, включится *.h файл и будет все выглядеть вот так вот:
              ExpandedWrap disabled
                // child.tmp - это выходной файл, который сгенерируется после того, как отработает препроцессор
                 
                class Cchild: public Cbase
                {
                //...
                };
                 
                 
                class Cbase
                {
                //...
                };
                 
                ...
                //! Реализация Cchild

              И выходит, что в точке, где ты объявляешь свой класс Cchild - компилятор ничего не знает про тот класс, от которого ты наследуешься(в твоем случае про класс Cbase), он узнает о том, где он объявлен и что это за класс уже ниже. А до этого он про него не знает, вот он тебе и говорит - я не знаю что за такой класс, от которого ты наследуешься.
              Сообщение отредактировано: KILLER -
                Спасибо :thanks:

                Не думал, что препроцессор так переворачивает подключения :unsure: :blink:
                Всегда так подключал
                ExpandedWrap disabled
                  *.cpp
                  //все включения
                  #include <>
                  ...
                  e.g.:#include "base.h"
                   
                  ...
                  e.g.:#include "child.h"
                   
                  Cchild::Cchild() {}
                  //И т.д.
                  //...


                Не жалую я подключения хидеров в *.h-файлы!
                  Цитата agapUP @
                  Не жалую я подключения хидеров в *.h-файлы!

                  Ну почему же? Если в *.h файле есть зависимость, то пусть он хэдер с этой зависимостью и подключает.
                    Цитата agapUP @
                    Не думал, что препроцессор так переворачивает подключения :unsure: :blink:

                    Ничего он не переворачивает, в С/С++ единица компиляции считается с/cpp файл. #include - макрос

                    вот ты пишешь:
                    ExpandedWrap disabled
                      //! File: A.h
                      #ifndef _A_H_
                      #define _A_H_
                       
                      class A
                      {
                      ...
                      };
                      #endif


                    ExpandedWrap disabled
                      //! File: A.cpp
                      #include "A.h"
                      //! реализация
                      A::A()
                      {
                      ...
                      }
                      ...

                    В итоге у тебя есть 1 класс, который разнесен на два файла, как только ты запустишь компиляцию, препроцессор вместо строчки #include "A.h" подставит содержимое этого файла(к слову так даже массивы можно объявлять.)
                    А теперь расскажи следующее, ты написал:
                    ExpandedWrap disabled
                      //! File: A.h
                      #ifndef _A_H_
                      #define _A_H_
                       
                      class A : public CBase
                      {
                      ...
                      };
                      #endif

                    Что такое CBase ? Верно ты не знаешь, а с какого перепуга компилятор должен об этом узнать? Другое дело, что есть инструменты сказать компилятору о том, чтоб он особо не ругался, т.к. какой нибудь класс уже где то объявлен, например это касается forward declarations, но допустимы если у тебя ссылочный тип данных или указатель. А тут наследование, соответственно, чтобы компилятор знал что это за тип, ему его нужно объявить, а у тебя идет использование типа до того, как ты его объявил.
                    Сообщение отредактировано: KILLER -
                      Скрытый текст
                      Цитата KILLER @
                      #include - макрос

                      Если точнее - директива препроцессора.
                        Доброе время суток
                        Спасибо, что уделяете мне время :thanks:
                        KILLER, спасибо за разъяснения :thanks:

                        НО!! Чем мой пример отличается от концепции С++?! :unsure: :blink:
                        Прошу у Вас прощения :blush: , видать я не очень наглядно продемонстрировал вопрос...
                        Попытаюсь исправить:

                        ExpandedWrap disabled
                          //ipo1.h
                          clas Cipo: public CCommAlg
                          {
                          //...
                          };
                          //...
                          //Конец ipo1.h
                           
                          //ipo1.cpp
                           
                          #include <vector>
                          //...
                          #include <string>
                          #include <hrono>
                          //...
                           
                          #include "CommAlg.h" !!!!!!!!!!!!!!!!!!!!!!!!!!
                          //...
                          #include "ipo1.h" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                           
                          /*
                          РЕАЛИЗАЦИЯ МЕТОДОВ Cipo1
                          */
                           
                          //Конец ipo1.cpp


                        Так вот чем может (по концепции) реализация в ipo1.cpp:
                        ExpandedWrap disabled
                          //...
                          #include "CommAlg.h"
                          //...
                          #include "ipo1.h"
                          //...

                        Может отличаться от:
                        ExpandedWrap disabled
                          #pragma once
                          #include "CommAlg.h"
                          class Cipo: public CCommAlg

                        ? :unsure:
                        Ведь поля класса типа string определяются в описании самого класса, хотя включение этой библиотеки
                        осуществляется в ipo1.cpp!!!

                        Использую компилятор VS2012


                        Цитата Kray74 @
                        Ну почему же? Если в *.h файле есть зависимость, то пусть он хэдер с этой зависимостью и подключает.
                        Знаете... Для меня это как-то не убедительно звучит! Вот пример, стандартные библиотеки, типа #include <string> - у меня и в мыслях нет их в хедер загонять!!!!! Даже и не экспериментировал! Когда использовал "ifndef ..." - компелятор ругался о многократном включении. Вот и сформировалось у меня такое представление. А зависимость показана в реализации: файл ipo1.cpp
                        Сообщение отредактировано: agapUP -
                          Цитата agapUP @
                          Вот пример, стандартные библиотеки, типа #include <string> - у меня и в мыслях нет их в хедер загонять!!!!

                          а это потому что ты не наследуешься от них. зафорвардить можно только классы, да и то только если будешь использовать указатели - так как они занимают фиксированный объём. ну еще енумы всякие. а если ты хочешь в хидере обьявить сам объект или наследоваться, то тогда надо делать инклюд, иначе компиль не знает сколько места надо выделить под эти объекты.
                          Сообщение отредактировано: _lcf_ -
                            Цитата agapUP @
                            НО!! Чем мой пример отличается от концепции С++?! :unsure: :blink:

                            В каком смысле? По концепции С++, ты написал неработающий код. Смотри? давай на пальцах, вот что ты написал:
                            ExpandedWrap disabled
                              int main()
                              {
                               
                                 int x = 10;
                                 int result = x + y;
                                 int y = 20;
                               
                                 std::cout << "x+y=" << result;
                                 return 0;
                              }

                            Компилятор тебе говорит - "Я не знаю что за такая переменная y в выражении int result = x + y;"
                            Что тут не понятного?

                            Цитата agapUP @
                            Ведь поля класса типа string определяются в описании самого класса, хотя включение этой библиотеки
                            осуществляется в ipo1.cpp!!!

                            Чего? Если ты не подключишь string в хидер, но будешь его там использовать - будет ровно такая же ошибка.

                            Цитата agapUP @
                            Когда использовал "ifndef ..." - компелятор ругался о многократном включении. Вот и сформировалось у меня такое представление. А зависимость показана в реализации: файл ipo1.cpp

                            компилятор может ругатся о многократном включении, если отсуствуют гарды компиляции:
                            ExpandedWrap disabled
                              #ifndef __SOME_HEADER_FILE__ //! гард предотвращающий повторное включение хидера.
                              #define __SOME_HEADER_FILE__
                               
                              //! Какие то объявления
                              #endif
                              agapUP
                              все указанные инклюды препроцесовр включает в файлы cpp, причем в каждый cpp, но повторов нет из-за #pragma once
                                Доброе время суток
                                Цитата _lcf_ @
                                ...иначе компиль не знает сколько места надо выделить под эти объекты.

                                Я не берусь судить, ибо не знаю! :huh: :D, но после этих строк мне чет зачесалось в пятой точке ;), что мои траблы связаны с выделением-затиранием память процесса :unsure:

                                ВОТ! Один проект! Два дочерних и один базовый:

                                ...

                                А скрины вставить не вышло.....

                                Но там суть такая: для класса А я хидер базового включил в срр-файл класса А - и ошибки "С2504 - не определен базовый класс" не возникло!
                                А для класса B - эта ошибка возникла! :unsure:

                                Добавлено
                                Всем спасибо :thanks:
                                Сообщение отредактировано: agapUP -
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0648 ]   [ 17 queries used ]   [ Generated: 29.03.24, 13:47 GMT ]