C++11 Преобразование традиционного указателя в интеллектуальный указатель.Использование актуальной версии SVN Clang и libc++ из llvm.

StackOverflow https://stackoverflow.com//questions/9666193

Вопрос

У меня есть функция внутри класса (A), которая по сути принимает в качестве параметра указатель на другой класс (B).Класс B наследуется множеством других классов, которые он также должен принять.

Я хотел бы взять на себя ответственность за этот указатель и сохранить его для последующего использования в классе, он больше не будет использоваться вне класса ни для чего другого.Хотя я бы сделал параметр общим_ptr, мне бы хотелось избегать этого, насколько это возможно, из-за того, что другие люди, с которыми я работаю, не совсем понимают всю суть умных указателей.Есть какой-либо способ сделать это?

Вот своего рода пример, который я хотел бы сделать, хотя, судя по тому, что я тестировал, это не работает.

//In .h file
std::vector< unique_ptr< B > > data_store;

//In .cpp file
void A::add_data(B* NewItem)
{
    data_store.resize(data_store.size()+1);
    data_store[data_store.size()-1] = NewItem;
}

Во-вторых, я хотел бы использовать конструктор копирования или что-то подобное, чтобы использовать интеллектуальный указатель внутри класса:то, что мне нужно сделать, может стать немного некрасивым, если мне придется удалять вручную.Проблема в том, что я не знаю, входит ли это в базовый класс (B) или в класс, унаследованный от B.Я не слишком уверен, как с этим справиться без необходимости жестко запрограммировать какой-то проверяемый идентификатор для класса и использовать правильные конструкторы копирования/перемещения, чего я хотел бы избежать любой ценой.

Я использую обновленные версии Clang и libC++ от llvm, которые я обновил около 10 утра по британскому времени 12 марта 2012 года.

Это было полезно?

Решение

Для любого указателя, который не должен быть общим, и класс имеет единоличное владение std::unique_ptr<T> это правильный выбор.Он автоматически удалит указатель, когда объект-владелец выйдет за пределы области видимости или будет удален.На самом деле я бы вообще советовал не использовать для этого общий указатель, поскольку он сообщит другим разработчикам, что этот член должен быть общим.

Итак, о копировании.Поскольку у вас есть указатель на объект, который может иметь подклассы, вам необходимо использовать метод clone идиома вместо обычного конструктора копирования.Обычно это реализуется с помощью виртуального clone функция, которая возвращает указатель (или интеллектуальный указатель) на класс.Это требует, чтобы все подклассы переопределили это, вернув свою копию.

class Base {
    ...
    virtual std::unique_ptr<Base> clone() const = 0;
    ...
};

class Subclass {
    ...
    virtual std::unique_ptr<Base> clone() const {
        return std::unique_ptr<Base>(new Subclass(*this));
    }
};

Если у объекта-владельца есть конструктор копирования, ему придется вызвать эту функцию-член клонирования для объекта, которым он владеет, при создании своей копии.

Другие советы

Если вы хотите создать объект, которым принадлежит вектор указателей, которые вы должны использовать Boost :: Вектор PTR.Он автоматически удаляет все объекты, содержащиеся сам по себе

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top