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

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

    ExpandedWrap disabled
      #include <iostream>
      #include <cstddef>
       
      class Base {
          inline static std::size_t Counter;
          std::size_t Num;
        public:
          Base() {
              Num = Counter;
              Counter++;
          };
          std::size_t GetNum() {
              return Num;
          };
          std::string Where() {
              return "Placed in: "; // ??????????????????????????
          }
      };
       
      class Derived: public Base {};
       
      int main() {
        Base S1;
        Base S2;
        Derived *H1 = new Derived();
        std::cout << "S1: " << S1.GetNum() << std::endl;
        std::cout << "S2: " << S2.GetNum() << std::endl;
        std::cout << "H1: " << H1->GetNum() << std::endl;
      }

    Вывод даст:

    ExpandedWrap disabled
      S1: 0
      S2: 1
      H1: 2

    Естественно, тут все просто, обычная работа со статической переменной.

    А вот сам вопрос темы сложнее - как в объекте можно узнать где он разместился?
    Оставлять в конструкторе какой-то параметр, указывающий тип размещения - не варик, можно накосячить.
      Напрямую - никак. Конструктор вызывается после выделения памяти и никакой информации об области размещения не получает. Единственный, на мой взгляд, вариант решения - сделать конструктор защищенным (protected) и создавать объекты через фабрику, которая передаст в конструктор нужный параметр без косяков.
        Цитата Dushevny @
        Напрямую - никак. Конструктор вызывается после выделения памяти и никакой информации об области размещения не получает

        Да, похоже тут тупичок.

        Цитата Dushevny @
        Единственный, на мой взгляд, вариант решения - сделать конструктор защищенным (protected) и создавать объекты через фабрику, которая передаст в конструктор нужный параметр без косяков.

        Я попробовал вот какой вариант, естественно костыльный и непереносимый. Но, думаю, если писать под конкретную реализацию - как-то можно допилить. Это для GCC 12.1 x86_64:

        ExpandedWrap disabled
          #include <iostream>
           
          class Base {
              uint64_t sp;
            public:
              Base() {};
              void Print(){
                 asm("mov %%rsp, %0" : "=rm" ( sp ));        
                 std::cout << this << std::endl;
                 std::cout << "0x" << std::hex << sp << std::endl;
              }
          };
           
          int main() {
            Base S1;
            Base *H1 = new Base();
            S1.Print();
            H1->Print();
          }

        Выводит интересные цифры:

        ExpandedWrap disabled
          0x7ffe4345c4a0
          0x7ffe4345c480
          0xf04eb0
          0x7ffe4345c480
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0987 ]   [ 16 queries used ]   [ Generated: 25.04.24, 01:13 GMT ]