Возможно, вы захотите объяснить , почему вы хотите вручную обработать необработанную память.Я давно этого не делал, это то, для чего std::string
и std::vector
предназначены:
struct ResultStructure
{
// nothing else needed
std::string data; // or std::vector<char>
};
Но если вам действительно нужно сделать это нелегко (это домашняя работа?)затем имейте в виду, что на первый взгляд на удивление трудно понять это правильно.Например, наивная реализация оператора присваивания может выглядеть следующим образом:
// DON'T TRY THIS AT HOME!!
ResultStructure& ResultStructure::operator=(const ResultStructure& rhs)
{
delete[] ptr; // free old ressource
ptr = new char[rhs.length]; // allocate new resourse
std::copy(rhs.ptr, rhs.ptr+rhs.length, ptr; // copy data
length = rhs.length;
}
Если кто-то случайно назначил объект себе (что может произойти, если у вас есть только две ссылки, и вы их не подозреваетессылаться на тот же объект), то это приведет к фатальной неудаче.
Кроме того, что если new
выдает исключение?(Может выдать std::bad_alloc
, если память исчерпана.) Тогда мы уже удалили старые данные и не выделили новые данные.Однако указатель все еще указывает на то место, где раньше находились старые данные (на самом деле, я думаю, что это определяется реализацией, но мне еще предстоит увидеть реализацию, которая изменяет ptr при удалении), и деструктор класса (you знал , что классу нужен деструктор, верно?) Затем попытается удалить часть данных по адресу, где данные не выделены.Это неопределенное поведение .Лучшее, на что вы можете надеяться, это то, что он немедленно падает.
Самый простой способ сделать это - использовать идиому Copy-And-Swap :
struct ResultStructure
{
ResultStructure(const ResultStructure& other)
: ptr(new char[rhs.length]), length(rhs.length)
{
std::copy(rhs.ptr, rhs.ptr+rhs.length, ptr);
}
~ResultStructure() // your class needs this
{
delete[] ptr;
}
ResultStructure& operator=(ResultStructure rhs) // note: passed by copy
{
this->swap(rhs);
return *this
}
void swap(const ResultStruct& rhs)
{
using std::swap;
swap(length, rhs.length);
swap(ptr, rhs.ptr);
}
std::size_t length;
char* ptr;
};
Обратите внимание, что я добавил деструктор, изменил оператор присваиваниячтобы передать аргумент для каждой копии (нам нужен конструктор копирования, вызываемый для выделения памяти), и добавили функцию-член swap
.В соответствии с соглашением функция swap()
никогда не генерирует и является быстрой, предпочтительно O (1).
Я знаю, что Обсуждение GMan идиомы Копировать-и-Поменять достаточно исчерпывающе, чтобы быть исчерпывающим, в то время как мое , вероятно, слишком кратко для вас, и выскорее всего, сначала не поймешь, но постарайся проявить упорство и понять как можно больше.