В моем коде для численной физики мне нужно создать массив объектов Derived с помощью unique_ptr
, а их тип будет базовым. Обычно я бы:
// Header file of the Base class
class Particle{
public:
Particle(); // some constructor
virtual ~Particle(); // virtual destructor because of polymorphism
virtual function(); // some random function for demonstration
};
// Header file of the Derived class
class Electron : public Particle{
public:
Electron();
// additional things, dynamic_cast<>s, whatever
};
Позже в моем коде, чтобы создать массив объектов Derived с указателем Base, я бы сделал
Particle* electrons = new Electron[count];
Преимущество состоит в том, что я могу использовать массив в очень удобном способе electrons[number].function()
, потому что инкрементное значение в []
на самом деле является адресом памяти, указывающим на соответствующий экземпляр объекта Electron
в массиве. Однако использование raw-указателей становится беспорядочным, поэтому я решил использовать интеллектуальные указатели.
Проблема заключается в определении производных объектов. Я могу сделать следующее:
std::unique_ptr<Particle, std::default_delete<Particle[]>> electrons(new Electron[count]);
который создает массив полиморфных электронов и использует даже правильный вызов delete[]
. Проблема заключается в способе вызова конкретных объектов массива, поскольку я должен это сделать:
electrons.get()[number].function();
и мне не нравится часть get()
, а не немного.
Я мог бы сделать следующее:
std::unique_ptr<Particle[]> particles(new Particle[count]);
и да, вызовите экземпляры типа Particle
в массиве с помощью
particles[number].function();
и все будет хорошо и dandy, за исключением той части, что я не использую конкретные детали класса Electron
, поэтому код бесполезен.
И теперь для забавной части, допустим еще одну вещь, мы будем?
std::unique_ptr<Particle[]> electrons(new Electron[count]);
BOOM!
use of deleted function ‘std::unique_ptr<_Tp [], _Dp>::unique_ptr(_Up*) [with _Up = Electron; <template-
parameter-2-2> = void; _Tp = Particle; _Dp = std::default_delete<Particle []>]’
Что происходит?