Synoposis: конвертирует необработанные указатели в первом блоке кода ниже в интеллектуальные указатели, оставляя остальную часть функциональности как
без изменений.
Я писал код, в котором я пытаюсь передать указатель в конструктор объекта, чтобы сделать его указателем на созданный объект к тому времени, когда конструктор вернется.
(Примечание: это возникло в гораздо более сложной ситуации, но я упростил ее до сути проблемы. Таким образом, если вы попытаетесь спросить почему я делаю это, вы выиграли Не обязательно найти разумный ответ в этом контексте - но не в этом суть вопроса.)
После борьбы с реализацией интеллектуальных указателей я вернулся к необработанным указателям, чтобы убедиться, что не пропустил фундаментальную проблему:
#include <iostream>
class Thing {
public:
Thing(int data, Thing* thing_ptr) {
data_ = data;
*thing_ptr = *this;
}
void PrintData() {
std::cout << data_ << std::endl;
}
private:
int data_;
};
int main() {
Thing* thing_ptr;
Thing t(6, thing_ptr);
thing_ptr->PrintData();
return 0;
}
Это прошло без проблем, но когда я вернулся к умным указателям, я не мог воспроизвести эту функцию. Основная проблема в том, что я не знаю, как инициализировать умный указатель, не выполняя ненужную дополнительную работу или не ведя себя правильно.
Первое, что я попробовал, было:
#include <iostream>
#include <memory>
class Thing {
public:
Thing(int data, std::unique_ptr<Thing>& thing_ptr) {
data_ = data;
thing_ptr = std::unique_ptr<Thing>(this);
}
void PrintData() {
std::cout << data_ << std::endl;
}
private:
int data_;
};
int main() {
std::unique_ptr<Thing> thing_ptr;
Thing th(6, thing_ptr);
thing_ptr->PrintData();
return 0;
}
, что, как я полагаю, завершится неудачей (дамп ядра во время выполнения), потому что this
на самом деле не указатель на Thing
, а скорее указатель на неинициализированный блок памяти с подходящим размером для хранения Thing
. На самом деле я не уверен на 100%, что здесь происходит, но, поскольку это не удалось как с unique_ptr
, так и с shared_ptr
, я решил сначала инициализировать смарт-указатель, а затем присвоить this
его содержание.
Проблема в том, что я не могу обойтись без создания дополнительного объекта с помощью этого метода (который в свою очередь требует даже добавления дополнительного конструктора).
Thing() : data_(0) {}
Thing(int data, std::unique_ptr<Thing>& thing_ptr) {
data_ = data;
if (!thing_ptr) {
thing_ptr = std::make_unique<Thing>();
}
*thing_ptr = *this;
}
Здесь я делаю Thing::Thing()
только для того, чтобы выделить его на следующей строке, что, конечно, не является правильным подходом.
Может ли кто-нибудь умный указать мне правильное направление?