На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> локальные указатели на объекты
    Создаем объект, устанавливаем какое-то значение и передаем ссылку на этот объект в функцию, в которой создается указатель на объект такого же класса,его значение передается первому объекту, при выходе из функции локальный объект удаляется. Можно так делать или нельзя? Совсем запутался с этими указателями. Вроде работает..
    void main()
    {
    obj o;
    o.SetValue("before test");
    test(o);
    cout<<o.GetValue();
    }
    void test(obj &o)
    {
    obj* o2 = new obj;
    o2->SetValue("string from test");
    o=*o2;
    delete o2;
    }
    Выводит "string from test"
      Если есть конструктор копирования то работать будет, если нет то
      после удаления объекта из памяти твое -o- указыает на несуществующий объект
      т.е cout уже работать не должен, а должен падать smile.gif

      Вроде blink.gif так
      Сообщение отредактировано: Oksiv -
        сдается мне что у тебя в функции, ссылка с _о_ начинает указывать на _о2_, но по причине соответствующего деструктора в _obj_ текст не затирается посему и выводит "string from test"
          Все правильно он тебе выдал. После того как ссылка объявлена она считается синонимом объекта, на который ссылается. Т. е. в строчке
          CODE

          o=*o2;

          Ты копируешь содержимое объекта o2 в объект, на который ссылается o. Никакого присаивания значения одной ссылки другой (так, как если бы это были указатели) не происходит.
          Изменить значение ссылки ты можешь только в момент ее объявления и инициализации. Именно по этому на подобные конструкции:
          CODE

          obj& o;

          компилятор страшно ругается.
          Сообщение отредактировано: Flex_Ferrum -
            QUOTE
            o=*o2;

            Здесь работает оператор =, т.е. объект *o2 копируется в объект o.
            QUOTE
            delete o2;

            Здесь объект o2 удаляется
            Таким образом, по выходу из void test (obj &o), объект o, созданный в main, живет, но уже с измененной строчкой внутри (она меняется при o=*o2). Эта строчка и выводится в cout.
            Таким образом, если оператор = реализован правильно, то все выглядит верно. Сам объект o удалится по выходу из main, т.е. по окончании проги.
            Сообщение отредактировано: Uncle_Bob -
              оператор = я перегрузил там удаляется старая строчка выделяется память под новую и она заполняется значениями, копировщик соответственно простой *this=o2; значит все правильно и указателей вникуда мы не получим?
              А то с дельфей перехожу, кайфа от явной работы с указателями пока не ощущаю. Но че делать.. НАДО!
                Что значит
                QUOTE
                копировщик соответственно простой *this=o2
                ? Это у тебя так выглядит оператор присваивания?
                  Flex_Ferrum, неа, копировщик - в смысле копирующий конструктор

                  obj::obj(obj& o2)
                  {
                  *this=o2;
                  }

                  а оператор такой
                  obj& operator =(const obj& o2)
                  {

                  delete str;
                  str=new char[strlen(o2.GetValue()+1)];
                  strcpy(o2.GetValue());

                  } вот
                    тогда уж
                    CODE
                    obj::obj(obj& o2)
                    {
                     if (&o2 != this)
                       *this=o2;
                    }
                    Сообщение отредактировано: Uncle_Bob -
                      Вариант, конечтно, только есть два НО:
                      1. при конструировании str еще ничем не инициализировано, по этому delete str в операторе присваивания приведет к неопределенному результату.
                      2. если в программе встретится конструкция типа:
                      CODE

                      obj o;
                      o.SetValue("something");
                      o = o;

                      результат работы будет несколько неожиданным.
                      Отсюда советы:
                      1. перед вызовом *this = o2; сделай str = NULL;
                      2. В операторе присваивания добавь:
                      CODE

                      if (this == &o2)
                        return *this;
                      if (obj != NULL)
                        Flex_Ferrum, Uncle_Bob

                        про

                        if (this == &o2)
                        return *this;

                        и
                        проверку

                        if(str) // я просто опустил для краткости
                        delete str;

                        поясню про str:

                        private:
                        char* str;
                        //
                        obj::obj()
                        {
                        str=0;
                        }
                        вот так по частями весь класс описал...

                        достаточно ли строчку str инициализировать нулем в конструкторе по умолчанию? ну в смысле если объект создается копирующим конструктором будет ли всегда str==0 ?
                          При конструировании объекта вызывается только один конструктор, т.е. если вызван конструктор копирования, то конструктор по умолчанию не вызовется.
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


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