Статическое приведение к unique_ptr - PullRequest
0 голосов
/ 13 июня 2019

У меня есть файл заголовка, который должен скрывать некоторые внутренние компоненты по причинам сложности и "секретности".Поэтому у меня есть необработанный указатель void, объявленный в заголовке oublic, внутри кода есть статические приведения для преобразования необработанного указателя в его фактический тип.

Теперь из-за общих изменений управления памятью мне нужно изменить типвнутренне к unique_ptr (он идет от фабрики объектов теперь как unique_ptr, ранее это был необработанный указатель).

Так что в моем заголовке у меня есть это:

class SomeClass {
    private:
    void *_hiddenTypeInstance;
}

Возможно ли этостатическое приведение этого _hiddenTypeInstance к внутренне известному типу unique_ptr?

Ответы [ 2 ]

4 голосов
/ 13 июня 2019

Это не прямой ответ на то, что вы хотели, а предложение о том, как сделать все лучше :) На самом деле вы все еще можете использовать семантику памяти std::unique_ptr с сокрытием внутренних элементов и без использования уродливого void*.Как уже упоминали другие, вы должны изучить PIMPL, но подытожим:

  1. Вперед объявите внутренний тип в общедоступном заголовке
  2. Используйте std::unique_ptr с этим типом и предоставьте dtorдля класса, который содержит этот член (в противном случае вы получите ошибки компиляции, потому что будет сгенерирован dtor по умолчанию, который попытается удалить объявленный заранее класс и не сможет это сделать).

Это будетВыглядите примерно так:

#include <memory>

class CPrivate; // Forward declare the internal class

class CPublic
{
public:
    // You need the dtor here, since when you implement it in the .cpp of your library,
    // where the definition of CPrivate is known, the dtor of std::unique_ptr will know how to delete it.
    // If you do not put the dtor here, a default one will be generated here which invokes the dtor of std::unique_ptr, and here
    // since CPrivate is forward declared the dtor of std::unique_ptr will not know how to delete it and you will get an error
    ~CPublic();


private:
    std::unique_ptr<CPrivate> m_pPrivate;
}

Используя это, вы можете затем избежать приведения внутри реализации от void* к фактическому типу.

Что касается исходного вопроса - вывсегда может привести void* к std::unique_ptr<T>* (указатель на unique_ptr).Но я бы посоветовал оценить решение выше.Потому что вещь void* устраняет всю строгость типов - например, что произойдет, если кто-то изменит T?

0 голосов
/ 13 июня 2019

если я правильно понимаю вашу проблему: вот что вы можете сделать. Этот пример только для понимания концепции. Вы можете использовать его в своем собственном коде. Поскольку у меня нет всего кода, я не могу написать точное решение.

class SomeClass {
private:
    void *_hiddenTypeInstance;
public:
    std::unique_ptr<int> foo() {
        int a;
        a = 2;
        return std::unique_ptr<int>(&a);
    }
    void bar() {
        std::unique_ptr<int> temp_hidden_type_instance;
        temp_hidden_type_instance = std::unique_ptr<int>(static_cast<int*>(_hiddenTypeInstance));
        temp_hidden_type_instance = foo();
    }
};
...