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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Для чего в C++ был включен оператор размещения new 
:(
    Опции темы
Vladimiir
Дата 21.8.2010, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



 К примеру имеем:

Код
// -------------------------------------
//
class CountChar {

public:

CountChar() : m_Val(NULL) {
};

int  GetVal() { return  m_Val; };

void Add() { m_Val++; };

}

 private:    

 int  m_Val;

};

 INT  *pBuf = new INT[ sizeof( CountChar ) * 100 ];                        // Выделяем память, но не создаем объектов CountChar

// -------------------------------------
//
int main() {    

 CountChar  *pCountChar01 = new ( pBuf + 2 ) CountChar;           // Создаем объект CountChar в pBuf    
  
}


 Можно ведь того же результата достигнуть скажем так:

Код
 CountChar  CountChar02;

 memcpy( (INT *)(pBuf + 2),  &CountChar02, sizeof( CountChar ) );


 Я привел этот пример к тому что ведь в принципе чего мы достигаем использованием 
 оператором размещения new => размещаем что-нибудь в уже выделенной памяти.
 Так почему бы для достижения этой цели не использовать к примеру функцию memcpy?

Модератор: Не забываем пользоваться кнопочкой "Код"

Это сообщение отредактировал(а) bsa - 23.8.2010, 15:45
PM MAIL   Вверх
alexvs11
Дата 21.8.2010, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



new/delete были введены в С++ по сравнению с С для автоматического вызова конструктора/деструктора
к тому же он работает с динамической памятью, а ваш пример-опроверженье со статической времени компиляции

Это сообщение отредактировал(а) alexvs11 - 21.8.2010, 23:00
PM MAIL   Вверх
Vladimiir
Дата 21.8.2010, 23:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



  Вопрос затрагивает только одну из форм оператора new, а не всех его возможностей.

  Приведенный ведь пример по своей функциональности ни чем не уступает оператору new ...

  Да почему же со статической? Память то ведь pBuf была выделена динамически.
  А что касается чего мы там в нее пишем, так этот вопрос целиком зависит от потребностей алгоритма ...

Это сообщение отредактировал(а) Vladimiir - 21.8.2010, 23:18
PM MAIL   Вверх
alexvs11
Дата 21.8.2010, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



Код

#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;

class String{
public:
  String( const char* _data ) : data( new char[strlen(_data)+1] ){ strcpy( data, _data ); }
  ~String() { delete data; }
  const char* getData(){ return data; }
private:
  char* data;  
};

int main(){
  String* str2;
  {
    String str1 = String("hello world");
    cout << str1.getData() << endl;
    str2 = (String*)malloc( sizeof(String) );
    memcpy( str2, &str1, sizeof(String) );
  }
  cout << str2->getData() << endl;
}



ну вот можно сказать пример для размышления, так ли хорош метод
он кстати тоже динамический

речь идет о том, что простое копирование данных класса, в обход конструктора - может привести к некорректной работе его экземпляров

Это сообщение отредактировал(а) alexvs11 - 21.8.2010, 23:41
PM MAIL   Вверх
Vladimiir
Дата 21.8.2010, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



 ...   String( const char* _data ) : data( new char[strlen(_data) + 1] ){ strcpy( data, _data ); }
                                                                                                    ^
                                                                                                    ^- иначе затрем не свой байтик 

 
 Что-то не понял смысл примера. У тебя используется одна из форм new, которая выделяет динамически память.
 У меня же вопрос о форме оператора new, который не выделяет память, а размещает данные уже в выделенной памяти.
 Наверное я то-то не улавливаю из твоего примера, на что ты делаешь намек ...
 Поясни.

  Да конечно оператор new, который размещает данные вызывает constructors копируемого объекта. 
  А пример не мог бы привести или ссылку где посмотреть на такой пример ..
  Не очень я что-то этот момент чувствую. Ведь в изначальном примере, который я привел уже имеем объект CountChar02 у которого
  все constructors отработали и мы просто делаем его дубль. Зачем может понадобиться повторный вызов его constructors?


Это сообщение отредактировал(а) Vladimiir - 22.8.2010, 00:20
PM MAIL   Вверх
jonie
Дата 22.8.2010, 00:03 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

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



смысл в том, что вы можете использовать свой аллокатор для объекта.. например, размещать не "по умолчанию" объекты, а в нужном сегменте (не забывайте, что С++ работает на разных аппаратных платформах)
Цитата


 Так почему бы для достижения этой цели не использовать к примеру функцию memcpy?
memcpy вовсе не всегда даст вам то что надо. Например пусть ваш объект регистрируется в каком-либо глобальном кеше посредством заполнения в этом глобальном кеше указателя на себя из своего конструктора. Memcpy испортит ваш кеш.

Это сообщение отредактировал(а) jonie - 22.8.2010, 00:04


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
alexvs11
Дата 22.8.2010, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



имелся в виду не этот new, а сам main, копирование объекта в str2, 

Цитата

CountChar  *pCountChar01 = new ( pBuf + 2 ) CountChar;           // Создаем объект CountChar в pBuf  

вот вы же говорите - создаем объект, а это значит вызываем его конструктор. При тупом memcpy вызова конструктора не будет, в вашем случае это нормально, но примените memcpy для классов работающих например с динамической памятью (как String) и это приведет к ошибкам

char arr[sizeof(String)];
String* str2 = new((String*)arr)("hello"); не приведет к ошибке 
еще лучше, если мы напишем конструктор копирования String::String(const String&)
String* str2 = new((String*)arr)(str1);
PM MAIL   Вверх
Vladimiir
Дата 22.8.2010, 00:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




 ... Например пусть ваш объект регистрируется в каком-либо глобальном кеше посредством заполнения в этом глобальном кеше указателя
      на себя из своего конструктора. memcpy испортит ваш кеш.

  ^- в данном случае в cach просто не будет данных об новом объекте, что тоже плохо для случая когда данные об объекте должны в
       cach присутствовать.

 Пожалуй вы правы. Для простых объектов все будет Ok, но это будет не корректно в каких-нибудь "сложных" объектах.
 Да тот же COM объект если таким образом скопировать не увеличит свои счетчики ...
 
  А как все же можно было с помощью memcpy скопировать объект и выполнить нужный нам конструктор?

Это сообщение отредактировал(а) Vladimiir - 22.8.2010, 00:52
PM MAIL   Вверх
alexvs11
Дата 22.8.2010, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


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

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



нет, конструктор потому и конструктор что объединяет создание объекта и его инициализацию

кстати, а зачем вам это? неужто есть практическое применение? smile 
можно вынести инициализацию в отдельную функцию, но смысл конструктора тогда теряется

Это сообщение отредактировал(а) alexvs11 - 22.8.2010, 01:07
PM MAIL   Вверх
Vladimiir
Дата 22.8.2010, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




  Еще об этом не думал ... Просто интересно ... Ведь в этом случае мы нарушим устои C++. 
  Скорее всего это конечно можно сделать через ASM ...
  А вообще ради интереса покапаю немножко исходники RTM польза от этого всегда будет ..
  Я так например никогда не обращал внимания на то что strncpy согласно MSDN
  "... If count is greater than the length of strSource, the destination string is padded with null characters up to length count".
  А как то при отладке заглянул в исходник смотрю ... инициализирует.
  Не знаю как у кого, а у себя замечаю, что зачастую "костенею" в каком-нибудь вопросе и забываю о том, что он имеет еще
  какие-либо ньансы ... 
  Поэтому иногда зная в себе этот недостаток "обновляю" свой cach.

PM MAIL   Вверх
xvr
Дата 23.8.2010, 14:56 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Vladimiir @  22.8.2010,  00:42 Найти цитируемый пост)
А как все же можно было с помощью memcpy скопировать объект и выполнить нужный нам конструктор?
Собственно placement new и есть этот самый 'вызов конструктора'


PM MAIL   Вверх
Vladimiir
Дата 25.8.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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




  Ну хорошо немножко перефразирую вопрос. 
  Как вызвать  какой-либо  конструктор в уже созданном объекте.
PM MAIL   Вверх
bsa
Дата 25.8.2010, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

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



Цитата(Vladimiir @  25.8.2010,  12:22 Найти цитируемый пост)
Как вызвать  какой-либо  конструктор в уже созданном объекте. 

Через размещающий new. Но зачем?!?

Это сообщение отредактировал(а) bsa - 25.8.2010, 12:07
PM   Вверх
EvilsInterrupt
Дата 25.8.2010, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

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



>>Как вызвать  какой-либо  конструктор в уже созданном объекте.
какова цель?
PM MAIL WWW ICQ Jabber   Вверх
xvr
Дата 25.8.2010, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Vladimiir @  25.8.2010,  11:22 Найти цитируемый пост)
Как вызвать  какой-либо  конструктор в уже созданном объекте. 
Если объект создан, то какой то конструктор УЖЕ был вызван. И если для него позвать ЕЩЕ один конструктор (без предварительного разрушения объекта деструктором), то это черевато как минимум утечками ресурсов.


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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