Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> конструкторы копий и операторы присваивания, какой-то глюк ? 
:(
    Опции темы
M9IC
Дата 24.12.2010, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 20.12.2007

Репутация: нет
Всего: нет



Здарова, народ!

Разбираюсь с конструкторами копирования и перегрузкой операторов, есть вот такой код:

Классы:
Код

class Objct
{
    static int cnt;
    
public:
    int val;
    Objct( int v ): val(v){ ++cnt; }
    Objct( const Objct & copyme )
    { 
        ++cnt; 
        val = cnt ;
    }
};

int Objct::cnt = 100;

template< class Any >
class MP //MasterPointer
{
    Any * pData;
public:
    MP(): pData(NULL){}
    MP( Any data ): pData(&data){  }// идет вызов конструктора копий класса Objct !
    MP( const MP< Any > & mp ) //: pData( new Any(*mp.pData) ) 
    {
        pData = new Any(*mp.pData) ; //идет вызов конструктора копий класса Objct ? Да !
        int i = 6;
        ++i;
    } // copy constructor
    //MP( const MP< Any > & mp ): pData( *(mp.pData) ) {} // copy constructor from book, does`not working !
    MP< Any > & operator=( const MP< Any > & right);// prisvaivanie
};

template< class Any >
MP< Any > &  MP< Any >::operator =(const MP<Any> & right)
{
    if( & right == this ) return * this;
    if(pData)delete pData; // a esli on ni na chto ne ykazival ???

    pData = new Any( *right.pData ) ;// конструктор копий right не вызывается ???
    
    return * this;
}



Код

    MP<Objct> mpSlon;

    Objct Ydav(100);    
    MP<Objct> mpYdav(Ydav); // вызывается конструктор копии Objct ? Да вызывается !
    MP<Objct> mpYdav2 = mpYdav;   //конструирование ! НЕ присваивание !
    MP<Objct> mpYdav21 = mpYdav2; //конструирование ! НЕ присваивание !
    MP<Objct> mpYdav22 = mpYdav21; //конструирование ! НЕ присваивание !
    Objct * pYdav = & Ydav ;

После выполнения 5ой строки, херятся данные (перем. val) в экземпляре mpYdav, почему ? 
студия ВС 2005

вот скрины:
До
user posted image
после
user posted image

ПОЧЕМУ ?
PM MAIL   Вверх
Cheloveck
Дата 24.12.2010, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(M9IC @  24.12.2010,  17:16 Найти цитируемый пост)
Код

MP( Any data ): pData(&data){  }// идет вызов конструктора копий класса Objct !

С чего это у тебя он тут "идёт"? Ты присваиваешь указателю pData адрес переданного объекта. Это, почти всегда, плохо.

Цитата(M9IC @  24.12.2010,  17:16 Найти цитируемый пост)
Код

    MP( const MP< Any > & mp ) //: pData( new Any(*mp.pData) ) 
    {
        pData = new Any(*mp.pData) ; //идет вызов конструктора копий класса Objct ? Да !
        int i = 6;
        ++i;
    } // copy constructor

Где ты собираешься высвобождать память и как отличишь от того, что тебе передали?

Цитата(M9IC @  24.12.2010,  17:16 Найти цитируемый пост)
Код

if(pData)delete pData; // a esli on ni na chto ne ykazival ???


На NULL можно не проверять, но вот если будет адрес переданного объект - случиться анхендлед эксцепшен.




--------------------
user posted image
PM Jabber   Вверх
M9IC
Дата 28.12.2010, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 20.12.2007

Репутация: нет
Всего: нет



Код

MP( Any data ): pData(&data){  }// идет вызов конструктора копий класса Objct !

Цитата(Cheloveck @  24.12.2010,  18:05 Найти цитируемый пост)
С чего это у тебя он тут "идёт"? Ты присваиваешь указателю pData адрес переданного объекта. Это, почти всегда, плохо.


Ну как же? Я же передаю объект по значению, а не адресс или сцылку. Сначала происходит копирование для передачи в функцию, а потом от этого уже скопированного элемента я беру адрес.
Вот собсна и ответ напрашивается: потому-то там и получается мусор, так как скопированный элемент живет только в пределах функции.




Это сообщение отредактировал(а) M9IC - 28.12.2010, 16:44
PM MAIL   Вверх
M9IC
Дата 28.12.2010, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 20.12.2007

Репутация: нет
Всего: нет



если делать так:
Код
MP( Any data ): pData( new Any( data )){  }// идет вызов конструктора копий класса Objct !
То конструктор копий вызывается 2 раза, а этого не нужно, получается надо так:
Код
MP( const Any & data ): pData( new Any( data )){  }// идет вызов конструктора копий класса Objct !

Код

if(pData)delete pData; // a esli on ni na chto ne ykazival ???
Цитата
На NULL можно не проверять, но вот если будет адрес переданного объект - случиться анхендлед эксцепшен.
так я же вначале проверяю на равность самому себе:
Код

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

Цитата
Где ты собираешься высвобождать память и как отличишь от того, что тебе передали?

Не совсем понял, что я должен от чего отличить ?
собирался делать так:
Код

~destructor()
{
  delete pData; // Разве так нельзя сделать, почему ?
}


Это сообщение отредактировал(а) M9IC - 28.12.2010, 16:46
PM MAIL   Вверх
Cheloveck
Дата 28.12.2010, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



pData у тебя объявляется как указатель на Any. 
Цитата(M9IC @  24.12.2010,  17:16 Найти цитируемый пост)
 MP( Any data ): pData(&data){  }// идет вызов конструктора копий класса Objct !

здесь ты берёшь адрес параметра и присваиваешь его указателю pData.Никаких конструкторов копирования не вызывается. Когда Вызывающая функция уничтожает переданный параметр, то твой pData указывает в никуда!


Делать надо примерно так
Код

MP( Any & data ): pData(new Any(data)){  }


Это сообщение отредактировал(а) Cheloveck - 28.12.2010, 18:50


--------------------
user posted image
PM Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0879 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.