Я было показано это std::string
не может быть вставлен в boost::lockfree::queue
,
boost::lockfree::queue
слишком ценный, чтобы отказаться, поэтому я думаю, что я мог бы использовать очень большую фиксированную длину char
s для передачи данных в соответствии с требования (при условии, что это даже удовлетворяет, так как у меня возникают проблемы с изучением того, как удовлетворить эти требования), но это потребляет память, если я хочу большие сообщения.
Существует ли текстовый объект динамического размера с конструктором копирования, тривиальным оператором присваивания и тривиальным деструктором? Если так, то где? Если нет, пожалуйста, опишите, как это сделать.
Тип динамического размера с тривиальной копией ctor / dtor невозможен. Есть два решения вашей проблемы: использовать тип фиксированного размера или хранить указатели в очереди:
boost::lockfree::queue<std::string*> queue(some_size);
// push on via new
queue.push(new std::string("blah"));
// pop and delete
std::string* ptr;
if(queue.pop(ptr))
{
delete ptr;
}
Существует ли текстовый объект динамического размера с конструктором копирования, тривиальным оператором присваивания и тривиальным деструктором?
Динамический размер, нет. Чтобы что-то иметь тривиальный деструктор, требуется, чтобы деструктор объекта был неявным (или дефолтным), а любые нестатические объекты-члены также имели неявные (или дефолтные) деструкторы. Поскольку все, что выделяется динамически, потребует delete []
где-то вдоль линии в деструкторе вы не можете выполнить это ограничение.
Чтобы расширить вышесказанное, рассмотрим (очень урезанный) пример того, что происходит в std::string
:
namespace std
{
// Ignoring templates and std::basic_string for simplicity
class string
{
private:
char* internal_;
// Other fields
public:
string(const char* str)
: internal_(new char[strlen(str) + 1])
{ }
};
}
Посмотрим, что произойдет, если мы оставим деструктор по умолчанию: он уничтожит выделенный стек char *
(то есть указатель сам, не то, что это указывает на). Это может привести к утечке памяти, поскольку теперь мы выделили пространство, которое не имеет ссылок и, следовательно, никогда не может быть освобождено. Итак, нам нужно объявить деструктор:
~string()
{
delete[] internal_;
}
Однако, делая это, деструктор становится определяемым пользователем и, следовательно, нетривиальным.
Это будет проблемой для всего, что распределяется динамически. Обратите внимание, что мы не можем это исправить, используя что-то вроде shared_ptr
или vector<char>
как переменная-член; даже если они могут быть выделены в нашем классе стека, они просто позаботятся об управлении памятью для нас: где-то на линии с ними, есть new []
и соответствующий delete []
следовательно, они будут иметь нетривиальные деструкторы.
Чтобы удовлетворить это, вам нужно использовать выделенный стек char
массив. Это означает отсутствие динамического распределения и, следовательно, фиксированный размер.