unique_ptrпутаница - PullRequest
       7

unique_ptrпутаница

0 голосов
/ 08 ноября 2019

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

class A {
private:
public:
    A(std::unique_ptr<char[]> data) {
        data = nullptr;
    }
    ~A();

};
int main() {
    auto data = std::make_unique<char[]>(10);
    A a(std::move(data));
    return 0;
 }

Следующий вопрос, который у меня возникает: если у меня есть закрытый объект, на который я хочу указать данные, почему это приводит к компиляторуошибка?

class A {
private:
    std::unique_ptr<char[]> internaldata;
public:
    A(std::unique_ptr<char[]> data) {
        internaldata = data;
    }
    ~A() {
        internaldata = nullptr;
    }

};
int main() {
    auto data = std::make_unique<char[]>(10);
    A a(std::move(data));
    return 0;
 }

Однако, когда я вызываю std :: move при назначении, код компилируется нормально.

class A {
private:
    std::unique_ptr<char[]> internaldata;
public:
    A(std::unique_ptr<char[]> data) {
        internaldata = std::move(data);
    }
    ~A() {
        internaldata = nullptr;
    }

};
int main() {
    auto data = std::make_unique<char[]>(10);
    A a(std::move(data));
    return 0;
 }

Но почему я должен дважды вызывать std :: move здесь? ? Один раз для передачи аргумента, затем второй для назначения? И что именно происходит с точки зрения подсчета ссылок во время этого процесса, происходит ли перераспределение, копирование и удаление?

И, наконец, возможно ли передавать данные в интеллектуальный указатель во время замедления? Потому что в настоящее время я делаю это так:

    auto data = std::make_unique<char[]>(10);
    char* buf = data.get();
    strcpy(buf, "hello\0");

Но возможно ли сделать что-то вроде:

    char hellobuffer[] = "hello";
    auto data = std::make_unique<char[]>(hellobuffer);

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

1 Ответ

4 голосов
/ 08 ноября 2019

Я знаю, что деструктор вызывается автоматически, когда больше нет ссылок на объект, но он все тот же для примитивных переменных?

Деструктор всегда вызывается логически. Однако, поскольку такие вещи, как int и char являются тривиально разрушаемыми, компилятор понимает, что на самом деле ничего не должно вызываться.

Например, если я это сделаю, будет ли удалена память?

Да - суть std::unique_ptr<T> в том, что ваша память автоматически обрабатывается.

A(std::unique_ptr<char[]> data) {
    internaldata = data;
}

Этот пример не компилируется, поскольку internaldata = data вызывает копиюоператор присвоения и копирования std::unique_ptr экземпляров запрещен (отсюда и уникальный бит).

И что именно происходит с точки зрения подсчета ссылок во время этого процесса, происходит ли перераспределение, копирование и удаление?

Счетчик ссылок отсутствует - a std::unique_ptr либо ссылается на что-то, либо оно пустое. Когда вы std::move из std::unique_ptr, перемещенная переменная становится пустой. Если вы ищете тип указателя с подсчетом ссылок, см. std::shared_ptr<T>.

И, наконец, возможно ли передавать данные в интеллектуальный указатель во время замедления?

Нет. Для std::make_unique<T[]> вам разрешено передавать только std::size_t (см. перегрузка 2 ). Должно быть легко написать функцию-обертку для того, что вы ищете.

...