На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> C++ интересный трабл с наследованием , наследование
    Недавно столкнулся с такой проблемой:
    Есть базовый класс, который наследуется другим,
    в базовом классе есть массив вещественных чисел Coord[3].
    Я бы хотел получить доступ к этим числам из дочернего
    класса, но не как к массиву, а как к полям структуры.
    Например, если бы Coord находился в дочернем классе, то
    все было бы просто:

    union {
     struct {
       float x, y, z;
     };
     float Coord[3];
    };

    Но косяк то в том, что Coord живет в базовом классе, и
    если такую хрень в него воткнуть, то он будет содержать
    2 массива Coord и Parent::Coord, в следствие чего размер
    увеличится на 12 байт (в 2 раза).

    Ктонибудь знает как решить эту проблему?
    Поделитесь идеями...
      class A
      {
      public:
      double coord[3];
      };

      class B : public A
      {
      public:
      double &x, &y, &z;
      B() : x(coord[0]), y(coord[1]), z(coord[2]){};
      };

      class C : public A
      {
      public:
      inline double & x(){return coord[0];};
      inline double & y(){return coord[1];};
      inline double & z(){return coord[2];};
      };

      Второй вариант не использует дополнительной памяти, но придется писать скобки, первый использует 3 указателя...

      еще можно

      class D
      {
      public:
      union __u
      {
       A a;
       struct __s{double x, y, x;} с;
      } c;
      }
      ...
      D.c.c.y = 12.0;

      но ето уже наглость, и она будет наказана...
      Сообщение отредактировано: Visitor -
        чтото я не понял, ты что хочешь полчить доступ к этементам массива как к полям структуры ? бред какой то, без обид dry.gif
          2 XilinX какой компилятор?
          (не увидел у тебя в примере имени объединения)

          У меня все получилось на VC6
          class CBase  
          {
          public:
          union
          {
           struct
           {
            float x, y, z;
           }u_Struct;
           float u_Coord[3];
          } m_Union;
          CBase(){}
          ~CBase(){}
          };

          //==========
          class CChild : public CBase  
          {
          public:
          int SomeMethod();
          CChild();
          ~CChild();
          };

          //==========
          CChild::CChild()
          {
          m_Union.u_Coord[0] = 1.222f;
          m_Union.u_Coord[1] = -0.0000263f;
          m_Union.u_Coord[2] = 1235.1234f;
          }

          CChild::~CChild(){ }

          int CChild::SomeMethod()
          {
          printf("coord_X = %f\ncoord_Y = %f\ncoord_Z = %f\n",
              m_Union.u_Struct.x,
              m_Union.u_Struct.y,
              m_Union.u_Struct.z);
          return sizeof(m_Union);
          }


          sizeof(m_Union); показывает 12, так как в VC размер float-а четыре байта, то есть VC приводит float к double.

          Я бы сделал по другому, в базовом классе, в секции protected:, создал инлайновый метод доступа к координатам, таким образом без разницы в каком виде хранятся координаты.

          ЗЫ. XilinX --- хороший ник wink.gif
            Я так понял, фишка в том, что декларацию базового класса менять нельзя?
              Еще раз перечитал вопрос. Видимо да, массив в базовом классе, и нужно в дочернем классе сделать структуру поверх массива в базовом классе. Разумеется так нельзя, папа и сын не могут иметь одну общую руку.

              Массив фиксированного размера, можно попробовать через дефайны

              #define _X_ (CBase::mCoord[0])
              #define _Y_ (CBase::mCoord[1])
              #define _Z_ (CBase::mCoord[2])
                Странно, я объявляю функцию как inline, однако просматривая ассемблерный код, вижу тот-же call
                  Цитата (MeG @ 6.12.03, 20:25)
                  Еще раз перечитал вопрос. Видимо да, массив в базовом классе, и нужно в дочернем классе сделать структуру поверх массива в базовом классе. Разумеется так нельзя, папа и сын не могут иметь одну общую руку.

                  Массив фиксированного размера, можно попробовать через дефайны

                  #define _X_ (CBase::mCoord[0])
                  #define _Y_ (CBase::mCoord[1])
                  #define _Z_ (CBase::mCoord[2])

                  Ты уверен, что нельзя?
                    Цитата (XilinX @ 7.12.03, 00:38)
                    Странно, я объявляю функцию как inline, однако просматривая ассемблерный код, вижу тот-же call

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

                    Добавлено в
                    Цитата (XilinX @ 7.12.03, 00:39)
                    Цитата (MeG @ 6.12.03, 20:25)
                    Еще раз перечитал вопрос. Видимо да, массив в базовом классе, и нужно в дочернем классе сделать структуру поверх массива в базовом классе. Разумеется так нельзя, папа и сын не могут иметь одну общую руку.

                    Ты уверен, что нельзя?

                    На сколько я понимаю, это противоречит одной из основных концепций ООП --- инкапсуляции.

                    Может я ошибаюсь, откуда у тебя такая идея взялась?
                    Сообщение отредактировано: MeG -
                      Вот что сказано у Страуструпа про встраиваемые функции.
                      Цитата

                          Функцию можно определить со спецификатором inline. Например:
                      inline int fac (int n) { return (n < 2) ? 1: n * fac (n - 1); }
                      Спецификатор inline указывает компилятору, что он должен пытаться каждый раз генерировать в месте вызова код, соответствующий функции fac () (факториал), а не создавать отдельно код функции (едножды) и затем вызывать ее посредством обычного механизма вызова. Хороший компилятор может сгенерировать константу 720 в месте вызова fac (6). В виду допустимости рекурсивных и взаимно рекурсивных встроенных функций, невозможно гарантировать, что в месте вызова такой функции будет действительно осуществлено встраивание кода функции. В зависимости от качества, один компилятор может сгенерировать 720, другой --- 6 * fac (5), а третий ---  обычный вызов fac (6).
                          Для того чтобы сделать возможным встраивание при отсутствии "сверхумного" компилятора и изощренных средств компоновки, определение (а не только объявление) встроенной функции должно находится в данной области видимости.
                        Идея отсюда:
                        Существует базовый класс, описывающий n-мерный вектор.
                        Дочерний клас описывает 3-х мерный вектор.
                        В базовом классе компоненты вектора живут в Coord[n],
                        хотелось бы реализовать доступ к ним как к полям структуры
                        из дочернего класса.
                        Обращение к полю структуры, это просто mov, а еслт делать
                        функцию float& X(), то это намного больше операций.
                          Цитата (XilinX @ 7.12.03, 02:55)
                          Идея отсюда:
                          Существует базовый класс, описывающий n-мерный вектор.
                          Дочерний клас описывает 3-х мерный вектор.
                          В базовом классе компоненты вектора живут в Coord[n],
                          хотелось бы реализовать доступ к ним как к полям структуры
                          из дочернего класса.

                          Базовый класс твой?

                          Цитата (XilinX @ 7.12.03, 02:55)
                          Обращение к полю структуры, это просто mov, а еслт делать
                          функцию float& X(), то это намного больше операций.

                          А если проверить?
                            В общем, не знаю что у тебя за компилятор,
                            VC, в release, с оптимизацией по скорости, делает абсолютно одинаковый код для
                            struct m_Struct { float x, y, z; } m_Struct;
                            float m_Coord[3];
                            inline float & Get_X() { return m_Struct.x; }

                            именно, доступ в одну строчку с индексным методом адресации относительно адреса объекта
                            fld DWORD PTR [ecx+8]
                            или
                            mov DWORD PTR [ecx+8], edx
                            Сообщение отредактировано: MeG -
                              Компилятор у меня VC (.NET) и вместо inline-подстановки он вставляет call
                                Цитата (XilinX @ 7.12.03, 15:15)
                                Компилятор у меня VC (.NET) и вместо inline-подстановки он вставляет call

                                Release?

                                Оптимизацию включал?

                                Обрати внимание на последний абзац в цитате Страуструпа
                                  Чо за фигня: у меня на странице свойств проекта нифига нет. Тоесть там есть пункты Optimization, Code Generation ect. но если на них тыкнуть, то нифига не появляется (собственно параметров)
                                  Сообщение отредактировано: XilinX -

                                  Прикреплённая картинка
                                  Прикреплённая картинка
                                    Ни у кого никаких идей? sad.gif
                                      Может нужно не отладочную (debug) версию собирать, а конечную (release)

                                      Тут ни у кого нет ни каких обязанностей перед тобой, так что 'пожалуйста', с твоей стороны, было бы в самый раз.
                                      Сообщение отредактировано: MeG -
                                        Цитата (MeG @ 9.12.03, 18:20)
                                        Тут ни у кого нет ни каких обязанностей перед тобой, так что 'пожалуйста', с твоей стороны, было бы в самый раз.

                                        И как ты себе представляешь последнее мое сообщение? Пожалуйста, ни у кого никаких идей? или Пожалуйста, идейку плииизз, умираю....... больше походит на какоето клянчание. Я же задаю реальный вопрос, и не потому, что мне позарез необходим ответ, а потому, что это интересный случай (не только для меня). И я не понимаю, что тебя так задело? Я никогда даже и не намекал, что кто-то тут мне что-то должен.
                                          Ну ты даешь blink.gif
                                          Тебе три раза на этой странице сказано: собирай release
                                            Цитата
                                            XilinX, 9.12.03, 11:14
                                            Ни у кого никаких идей?


                                            Нет, идей нет. Странный глюк обычно там все есть. Ты уверен, что это не пустой проект? А в других проектах показывает?

                                            Цитата
                                            И как ты себе представляешь последнее мое сообщение?


                                            Да все нормально ты написал, не понимаю что у MeG'a за претензии.
                                            Сообщение отредактировано: Fantasist -
                                              Я УВЕРЕН, что это не пустой прект..... в других тоже самое.
                                              MeG, при чем тут release, вопрос не в этом.....
                                              Сообщение отредактировано: XilinX -
                                                Цитата
                                                XilinX, 12.12.03, 09:54
                                                ..... в других тоже самое.


                                                Значит студия кривая. Попробуй переустановить. Вот и все идеи.
                                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                0 пользователей:


                                                Рейтинг@Mail.ru
                                                [ Script execution time: 0,0835 ]   [ 16 queries used ]   [ Generated: 3.05.24, 05:39 GMT ]